【问题标题】:Rails 4 - How to make a callback work only the first time a checkbox is clicked?Rails 4 - 如何使回调仅在第一次单击复选框时起作用?
【发布时间】:2015-09-23 01:39:47
【问题描述】:

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

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

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

【问题讨论】:

  • 你能用回调更新你的代码吗?
  • 完成,我已经用回调更新了帖子。

标签: ruby-on-rails ruby-on-rails-4 checkbox callback


【解决方案1】:

在第一次回调中设置 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

【讨论】:

  • 您能进一步解释一下吗?我不确定你的意思。我是新来的铁路。谢谢
  • 我为你更新了。将 invoiced_at 列添加到 Quote。
【解决方案2】:

我知道你接受了答案。但是不知道为什么需要这个额外的列。您可以通过两种方式在没有 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
    

【讨论】:

    【解决方案3】:

    试试

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

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

    【讨论】:

    • proc需要和“end”关键字吗?
    【解决方案4】:

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

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

    编辑:有人询问有关 javascript 的详细信息。您可以做的只是在单击时禁用表单元素。 (看起来不错,明白了。)这个 sn-p 将禁用页面上的任何复选框,因此如果您只想禁用某个类别的复选框,您只需将 input[type=checkbox] 替换为您要禁用的复选框。

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

    【讨论】:

    • 前端点击后隐藏复选框的代码是什么?我对 Rails 很陌生。
    • @davefogo 我添加了代码。这里假设 jQuery,它应该默认安装在每个新的 rails 应用程序中。
    • @Dan Ruswick 正在尝试通过
    猜你喜欢
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-14
    • 1970-01-01
    相关资源
    最近更新 更多