是否有任何区别:after_create:富VS after_commit:酒吧,:上=>:创建
after_create :after_create
和after_commit :after_commit_on_create, :on => :create
难道这可以互换使用?
是否有任何区别:after_create:富VS after_commit:酒吧,:上=>:创建
after_create :after_create
和after_commit :after_commit_on_create, :on => :create
难道这可以互换使用?
它们不可互换。关键区别在于回调运行时。在after_create
的情况下,这将始终在呼叫save
(或create
)返回之前。
Rails将每个save
包装在事务中,并且在该事务内部运行之前/之后创建回调(因此,如果在after_create中引发异常,保存将被回滚)。使用after_commit
,直到最外层事务提交后,您的代码才会运行。这可以是创建的事务栏或由您创建的事务栏(例如,如果您想在单个事务中进行多项更改)。
在after_save/create
运行时,您的保存仍然可以回滚并且(默认情况下)对其他数据库连接(例如,后台任务,如sidekiq)不可见。这些2的一些组合通常是使用after_commit
的动机。
这两者在协会方面有一个主要区别。只要为给定对象插入查询并且在插入查询对象关联之前立即调用after_create。这意味着关联对象的值可以直接在after_create回调中更改而不需要更新查询。
class Post < ActiveRecord::Base
has_one :post_body
after_create :change_post_body
def change_post_body
self.post_body.content = "haha"
#No need to save
end
end
这是否意味着如果after_commit提高和异常,那么它不会回滚先前提交的查询 –
正确(创建部分?) - 一旦交易已经comitted它不再被回滚 –
注意,当设置一个使用被创建对象的'id'的异步任务(例如通过sidekiq),那么你应该使用'after_commit,... on :: create',因为使用'after_create'你可以得到一个'ActiveRecord :: RecordNotFound'异常。这恰好发生在我们身上。 – Dschee