Rails 4 - 如何让回调仅在第一次点击复选框时起作用?

Rails 4 - How to make a callback work only the first time a checkbox is clicked?

如何使回调仅在第一次单击复选框时起作用?

一个"quote"模型有一个客户批准的复选框。这将启动一个生成发票的回调。但是,每次我选中和取消选中该框时,每次创建重复发票时都会启动回调。我怎样才能避免这种情况? 代码:

Class Quote<ActiveRecord::Base after_save :generate_invoice def generate_invoice Invoice.create!(date: self.date, quantity: self.quantity, unit_cost: self.unit_cost) end

在第一个回调集 invoiced_at 上,如果 invoiced_at 不存在,则在所有回调中仅开具发票

def generate_invoice
  if self.invoiced_at.blank?
    Invoice.create!(date: self.date, quantity: self.quantity, unit_cost: self.unit_cost)
    self.invoiced_at = Time.now
    self.save
  end
end

尝试

class Quote < ...
  after_save :generate_invoice, if: Proc.new { |q| q.checked.nil? }

或使用 after_create 如果它是在用户第一次单击复选框时创建的

您可以做一些事情。在创建操作中,您使用请求中的参数将登录名包装在 ! Invoice.find_by() 中。如果它已经存在,什么也不做。

在前端,您真的应该将一些逻辑附加到回调中,以便在选中时删除该复选框。让表单元素在页面上可见但什么也不做,或者让表单元素根据您单击它们的次数而表现不同,这不是好的约定。删除复选框将使用户清楚地知道发票已创建,他们无法采取任何进一步的操作。

编辑:有人在 javascript 上询问了细节。您可以做的只是在单击时禁用表单元素。 (看起来不错,明白了要点。)这个片段将禁用页面上的所有复选框,所以如果你只想禁用某个 class 的复选框,你只需将 input[type=checkbox] 替换为 class 您要禁用的复选框。

$('input[type=checkbox]').on('click', function(){$(this).attr("disabled", "true")})

我知道你接受了答案。但是不知道为什么需要这个额外的列。您可以通过两种方式在没有 invoiced_at 列的情况下做到这一点。

  1. 检查是否存在用于报价的发票。您的方案建议您的报价和发票模型中应该存在 has_onebelongs_to 关系。 所以像这样更改您的代码。

    def generate_invoice
      if self.invoice.present?
        Invoice.create!(date: self.date, quantity: self.quantity, unit_cost: self.unit_cost)
      end
    end
    
  2. 检查 Quote 模型中的 created_at 和 updated_at 列。他们第一次持有相同的价值观。所以你也可以像这样改变你的代码。

    def generate_invoice
      if created_at == updated_at
        Invoice.create!(date: self.date, quantity: self.quantity, unit_cost: self.unit_cost)
      end
    end