2012-07-27 64 views
6

我有一個註冊表單。Rails 3:rollback for after_create

當用戶註冊時,應用程序應該將數據保存在enrollments表和users表中。 (我需要這種分離,因爲用戶的個人資料可能會改變,但是他爲特定註冊輸入的數據必須存檔,所以即使後來用戶改變了他的姓氏,在註冊表中我也會得到他的初始信息。)

所以我想在enrollments表保存數據,然後有一個after_create呼叫,像這樣...

class Enrollment < ActiveRecord::Base 

    after_create :save_corresponding_user 

    def save_corresponding_user 
    user = User.new 
    user.full_name = self.user_full_name 
    user.email = self.user_email 
    user.mobile_phone = self.user_mobile_phone 
    user.save 
    end 
end 

的問題是,如果節省了用戶由於某種原因失敗。我如何回滾和銷燬enrollments表中剛剛保存的數據?

+0

用戶可以註冊幾次?如果不是,我只是直接在users表中添加額外的字段。 – 2012-07-27 17:15:47

+0

呃,實際上,這是一名家長/監護人將一名孩子招入日託。所以是的,家長可以多次註冊一個孩子。 – leonel 2012-07-27 17:22:39

+0

對我來說,似乎把save_corresponding_user放在after_create中會成爲一個問題。當用戶再次註冊時會發生什麼?你不想爲它們創建一個新的用戶對象。另外,註冊表中可能沒有user_id列嗎?這不會在上面的代碼中填充。如果是我,我只是將註冊和用戶的創建包裝在一個事務中,這將處理在發生錯誤時兩者的回滾。 – 2012-07-27 17:23:23

回答

12

after_create是保存當前模型的事務的一部分。因此,如果代碼崩潰或者after_create返回false,它應該回滾當前事務並使保存失效。

如果要模擬此,添加到您的after_create,看看是否一切正常:

raise Exception.new("CRASH") 
+0

如果您使用的是非事務數據庫(如mongodb),則不會發生回滾 – 2013-10-03 09:07:37

+3

如果after_create返回false,則不會顯示回滾事務(只是異常)。至少在Rails 4中。 – djburdick 2014-10-15 22:40:15

+0

@djburdick默認情況下事務只在引發異常時才應該回滾。所以這是預期的行爲。我認爲這個答案在細節方面略有不正確。 – leishman 2015-03-03 08:55:33

1

正如@anthonyalberto提到,after_create已經是交易的一部分。要定義一個事務,你會使用這樣的事情在你的控制器:

Enrollment.transaction do 
    @enrollment.save! 
end 

這真的是你需要做的,如果保存報名失敗或保存的用戶無法將回滾整個事務。以下是更多信息:http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html

7

after_create返回false什麼都不會做。

整個回調鏈被封裝在一個事務中。如果在回調方法返回完全爲false或引發異常之前,執行鏈會暫停併發出ROLLBACK;回調之後只能通過引發異常來實現。

此外,還必須raise ActiveRecord::Rollback

任何異常未的ActiveRecord ::回滾將被Rails的回調鏈暫停後重新升起。引發除ActiveRecord :: Rollback以外的異常可能會破壞不希望save和update_attributes(通常嘗試返回true或false)方法來引發異常的代碼。

http://guides.rubyonrails.org/active_record_callbacks.html#halting-execution

我做這樣的事情:

after_create do 
    if condition 
    errors.add(:attr, 'Blah blah blah.') 
    raise ActiveRecord::Rollback 
    end 
end 

對於Rails的3:http://guides.rubyonrails.org/v3.2.13/active_record_validations_callbacks.html#halting-execution