2013-11-22 47 views
0

我有一個UserReport模型連接用戶模型和報告模型。 (有很多通過關聯)。在父項創建上創建嵌套記錄

我有另一種叫做Comment的模型屬於UserReport。 (有很多關聯) 當創建一個報告時,我需要爲所有用戶創建一個UserReport,並提供一個默認評論。

我的問題是如何做到這一點,將回滾報表創建,如果任何一個子記錄保存失敗。

我的目標是確保數據庫不會停留在包含狀態。

有什麼建議嗎?

回答

0

如果您的模型是save,則整個過程將被包裝在一個事務中,如果保存失敗(由於驗證,回調等)將會回退。因此,如果您先在內存中構建整個對象樹,然後嘗試報告,則如果出現任何故障,則不會保存任何對象。

這裏有一個如何做到這一點的例子:

# in report.rb 
class Report < ActiveRecord::Base 
    validates_associated :user_reports 
end 

# in user_report.rb 
class UserReport < ActiveRecord::Base 
    validates_associated :comments 
end 

# in your controller or wherever you're doing this 
report = Report.new 
User.pluck(:id).each{ |user_id| report.user_reports.build(user_id: user_id) } 
report.user_reports.each{ |user_report| user_report.comments.build } 
report.save # will always save either everything or nothing, no inconsistencies 

注意使用#new#build以避免犯任何東西,直到最後一行。模型中的validates_associated行會導致子對象上的任何驗證錯誤傳播到父對象,即使父對象本身通過驗證也無法保存它。

2

你想要一個叫做事務的東西。該代碼會看起來像

begin 
    Report.transaction do 
    # create report like Report.create! or something 
    # create comments like Comment.create! or something 
    end 
rescue 
    # there was an error 
end 

的事務中,如果發生錯誤時將數據庫恢復到它是整個交易中開始了。在救援中,您可以處理任何拋出的錯誤。