2010-01-25 66 views
2

我有2種型號的before_filter或救援創造一個新的紀錄

class Room < ActiveRecord::Base 
    has_many :people 
    accepts_nested_attributes_for :people, :reject_if => lambda { |a| a[:person_id].blank? }, :allow_destroy => true 
end 

class Person < ActiveRecord::Base 
    belongs_to :room 
end 

在「/間/新」的形式我已經包含了所有的人+一個「其他」選項標籤,允許一個選擇標籤用戶將動態人物添加到選擇標記(新名稱)。

所以,當我提交我的表單時,我可以讓id = -1的人在數據庫中不存在,當然,我想用新名稱創建一個新的Person。

我在想什麼是達到這個目標的最好方法?

用「的before_filter」或「救助的ActiveRecord :: RecordNotFound」或...

感謝您的幫助

回答

2

按照一般的做法,我不會使用異常處理作爲控制建議功能邏輯。因此,我主張檢查id爲-1,並在這種情況下創建人員,而不是在救援塊中的事實之後這樣做。

如果你正在尋找一個理由,2我認爲是性能和清晰度。

例外情況非常昂貴,如果可以避免的話,您不希望產生處理成本。

此外,異常意味着指示錯誤狀態,而不是邏輯中的預期路徑。通過這種方式使用它們,你會渾水摸爬,看起來這並不意味着他的方式。通過在之前的過濾器中檢查一個非現存的人,更清楚的是有時會發生這種情況,並且清楚地知道這發生在剩餘的保存之前。另外,如果你在處理異常時做了這個邏輯,那麼你必須重試失敗的操作,通過循環或遞歸或者以其他方式複製失敗的保存,使得你的保存邏輯變得更加複雜。這也會使你的代碼不太清楚下一個必須處理它的編碼器。

+0

我同意你的看法,異常應該只使用捕獲錯誤而不是功能邏輯,謝謝您的回答 – denisjacquemin

2

你不需要任何特殊的代碼。 ActiveRecord已經包含處理這種情況的邏輯。

閱讀rdoc http://github.com/rails/rails/blob/2-3-stable/activerecord/lib/active_record/nested_attributes.rb#L328http://github.com/rails/rails/blob/master/activerecord/lib/active_record/nested_attributes.rb#L332瞭解詳情。從本質上講,如果哈希值是通過一個id關鍵字來傳遞記錄的屬性進行更新的。如果該記錄沒有:id鍵,則會創建一條新記錄。如果它有一個:id關鍵字和一個具有true'ish值的_destroy關鍵字,記錄將被刪除。

下面是2-3穩定分支的文件:

# Assigns the given attributes to the collection association. 
# 
# Hashes with an <tt>:id</tt> value matching an existing associated record 
# will update that record. Hashes without an <tt>:id</tt> value will build 
# a new record for the association. Hashes with a matching <tt>:id</tt> 
# value and a <tt>:_destroy</tt> key set to a truthy value will mark the 
# matched record for destruction. 
# 
# For example: 
# 
# assign_nested_attributes_for_collection_association(:people, { 
# '1' => { :id => '1', :name => 'Peter' }, 
# '2' => { :name => 'John' }, 
# '3' => { :id => '2', :_destroy => true } 
# }) 
# 
# Will update the name of the Person with ID 1, build a new associated 
# person with the name `John', and mark the associatied Person with ID 2 
# for destruction. 
# 
# Also accepts an Array of attribute hashes: 
# 
# assign_nested_attributes_for_collection_association(:people, [ 
# { :id => '1', :name => 'Peter' }, 
# { :name => 'John' }, 
# { :id => '2', :_destroy => true } 
# ])