是否有任何區別: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