Rails 4:如何取消保存" before_save"打回来?

时间:2014-05-23 20:04:02

标签: ruby-on-rails

我有复杂的模型/表格。我不想重复记录,所以我想合并具有相似属性的记录。如何使用before_save回调取消“保存”?这就是我的想法:

class ProductsColor < ActiveRecord::Base


  before_save :check_for_similar_record

  def check_for_similar_record
    if ProductsColor.exist?(color_id: self.color_id, product_id: self.product_id)
      # merge values with existing ProductsColor and stop self from saving
    end
  end

end

2 个答案:

答案 0 :(得分:54)

Rails 5

As of Rails 5,您可以通过在回调中明确调用throw :abort来表示应该中止操作。 cancelling callbacks(现在)的文档部分指出:

  

如果before_*回调throws :abort,则取消所有后续回调和相关操作。

关于transactions的以下部分继续:

  

如果before_*回调取消操作,则会发出ROLLBACK。您还可以在任何回调中触发ROLLBACK引发异常,包括after_*挂钩。

Rails 4

这个故事非常类似于Rails 5,除了回调应该返回falsethe documentation的相应部分有助于陈述

  

如果before_*回调返回false,则取消所有后续回调和相关操作。如果after_ *回调返回false,则取消所有后续回调。

其次是

  

如果before_ *回调取消操作,则会发出ROLLBACK。您还可以在任何回调中触发ROLLBACK引发异常,包括after_ * hooks。

答案 1 :(得分:29)

要阻止保存记录,您只需返回false

即可
def check_for_similar_record
  if ProductsColor.exists?(color_id: self.color_id, product_id: self.product_id)
    # merge values
    false
  else
    true
  end
end