我有复杂的模型/表格。我不想重复记录,所以我想合并具有相似属性的记录。如何使用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
答案 0 :(得分:54)
As of Rails 5,您可以通过在回调中明确调用throw :abort
来表示应该中止操作。 cancelling callbacks(现在)的文档部分指出:
如果
before_*
回调throws :abort
,则取消所有后续回调和相关操作。
关于transactions的以下部分继续:
如果
before_*
回调取消操作,则会发出ROLLBACK
。您还可以在任何回调中触发ROLLBACK
引发异常,包括after_*
挂钩。
这个故事非常类似于Rails 5,除了回调应该返回false
。 the 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