2013-04-01 45 views

回答

69

它們不可互換。關鍵區別在於回調運行時。在after_create的情況下,這將始終在呼叫save(或create)返回之前。

Rails將每個save包裝在事務中,並且在該事務內部運行之前/之後創建回調(因此,如果在after_create中引發異常,保存將被回滾)。使用after_commit,直到最外層事務提交後,您的代碼纔會運行。這可以是創建的事務欄或由您創建的事務欄(例如,如果您想在單個事務中進行多項更改)。

after_save/create運行時,您的保存仍然可以回滾並且(默認情況下)對其他數據庫連接(例如,後臺任務,如sidekiq)不可見。這些2的一些組合通常是使用after_commit的動機。

+8

這是否意味着如果after_commit提高和異常,那麼它不會回滾先前提交的查詢 –

+9

正確(創建部分?) - 一旦交易已經comitted它不再被回滾 –

+11

注意,當設置一個使用被創建對象的'id'的異步任務(例如通過sidekiq),那麼你應該使用'after_commit,... on :: create',因爲使用'after_create'你可以得到一個'ActiveRecord :: RecordNotFound'異常。這恰好發生在我們身上。 – Dschee

3

這兩者在協會方面有一個主要區別。只要爲給定對象插入查詢並且在插入查詢對象關聯之前立即調用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