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 列的情况下做到这一点。
检查是否存在用于报价的发票。您的方案建议您的报价和发票模型中应该存在 has_one
和 belongs_to
关系。
所以像这样更改您的代码。
def generate_invoice
if self.invoice.present?
Invoice.create!(date: self.date, quantity: self.quantity, unit_cost: self.unit_cost)
end
end
检查 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
如何使回调仅在第一次单击复选框时起作用?
一个"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 列的情况下做到这一点。
检查是否存在用于报价的发票。您的方案建议您的报价和发票模型中应该存在
has_one
和belongs_to
关系。 所以像这样更改您的代码。def generate_invoice if self.invoice.present? Invoice.create!(date: self.date, quantity: self.quantity, unit_cost: self.unit_cost) end end
检查
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