Rails 4:如何取消“before_save”回调上的保存?

时间:2022-01-13 01:19:53

I have complicated models / forms. I don't want repeated records, so I want to merge records that have similar attributes. How would I cancel "save" using a before_save callback? This is what I'm thinking:

我有复杂的模型/表格。我不想重复记录,所以我想合并具有相似属性的记录。如何使用before_save回调取消“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 个解决方案

#1


24  

To prevent record from being saved, you should simply return false:

为了防止记录被保存,您应该返回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

#2


45  

Rails 5

As of Rails 5, you can signal that an operation should be aborted by explicitly calling throw :abort inside your callback. The documentation section on cancelling callbacks (now) states:

从Rails 5开始,您可以通过显式地调用throw:abort在回调中来通知操作应该中止。关于取消回调(现在)的文件部分指出:

If a before_* callback throws :abort, all the later callbacks and the associated action are cancelled.

如果一个before_*回调抛出:abort,所有稍后的回调和相关操作将被取消。

The following section on transactions continues:

下一节继续讨论交易:

If a before_* callback cancels the action a ROLLBACK is issued. You can also trigger a ROLLBACK raising an exception in any of the callbacks, including after_* hooks.

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

Rails 4

The story is pretty similar to with Rails 5, except that callbacks should instead return false. The corresponding parts of the documentation helpfully states

这个故事与Rails 5非常相似,只是回调应该返回false。文档的相应部分提供了有用的说明

If a before_* callback returns false, all the later callbacks and the associated action are cancelled. If an after_* callback returns false, all the later callbacks are cancelled.

如果before_*回调返回false,则将取消以后的所有回调和相关操作。如果一个after_*回调返回false,则取消以后的所有回调。

Followed by

紧随其后的是

If a before_* callback cancels the action a ROLLBACK is issued. You can also trigger a ROLLBACK raising an exception in any of the callbacks, including after_* hooks.

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

#1


24  

To prevent record from being saved, you should simply return false:

为了防止记录被保存,您应该返回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

#2


45  

Rails 5

As of Rails 5, you can signal that an operation should be aborted by explicitly calling throw :abort inside your callback. The documentation section on cancelling callbacks (now) states:

从Rails 5开始,您可以通过显式地调用throw:abort在回调中来通知操作应该中止。关于取消回调(现在)的文件部分指出:

If a before_* callback throws :abort, all the later callbacks and the associated action are cancelled.

如果一个before_*回调抛出:abort,所有稍后的回调和相关操作将被取消。

The following section on transactions continues:

下一节继续讨论交易:

If a before_* callback cancels the action a ROLLBACK is issued. You can also trigger a ROLLBACK raising an exception in any of the callbacks, including after_* hooks.

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

Rails 4

The story is pretty similar to with Rails 5, except that callbacks should instead return false. The corresponding parts of the documentation helpfully states

这个故事与Rails 5非常相似,只是回调应该返回false。文档的相应部分提供了有用的说明

If a before_* callback returns false, all the later callbacks and the associated action are cancelled. If an after_* callback returns false, all the later callbacks are cancelled.

如果before_*回调返回false,则将取消以后的所有回调和相关操作。如果一个after_*回调返回false,则取消以后的所有回调。

Followed by

紧随其后的是

If a before_* callback cancels the action a ROLLBACK is issued. You can also trigger a ROLLBACK raising an exception in any of the callbacks, including after_* hooks.

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