2009-07-30 69 views
22

我已經升級到Rails 2.3.3(從2.1.x開始),我試圖找出accepts_nested_attributes_for方法。我可以使用該方法更新現有的嵌套對象,但我不能用它來創建新的嵌套對象。由於人爲的例子:如何使用accept_nested_attributes_for創建嵌套對象

class Product < ActiveRecord::Base 
    has_many :notes 
    accepts_nested_attributes_for :notes 
end 

class Note < ActiveRecord::Base 
    belongs_to :product 
    validates_presence_of :product_id, :body 
end 

如果我試圖創建一個新的Product,與嵌套Note,如下:

params = {:name => 'Test', :notes_attributes => {'0' => {'body' => 'Body'}}} 
p = Product.new(params) 
p.save! 

它失敗的消息驗證:

ActiveRecord::RecordInvalid: Validation failed: Notes product can't be blank 

我明白爲什麼會發生這種情況 - 這是因爲Note課程上的validates_presence_of :product_id,因爲在保存新記錄時,Product對象沒有id。但是,我不想刪除此驗證;我認爲刪除它是不正確的。

我也可以通過先手動創建Product,然後添加Note來解決問題,但是這樣做會使accepts_nested_attributes_for的簡單性失效。

是否有標準的Rails方式在新記錄上創建嵌套對象?

回答

16

這是一個常見的循環依賴問題。有一個existing LightHouse ticket值得一試。

我期望在Rails 3中這會得到很大的改善,但是在此期間你必須做一個解決方法。一種解決方案是設置一個虛擬屬性,它在嵌套時設置以使驗證有條件。

class Note < ActiveRecord::Base 
    belongs_to :product 
    validates_presence_of :product_id, :unless => :nested 
    attr_accessor :nested 
end 

然後,您將該屬性設置爲表單中的隱藏字段。

<%= note_form.hidden_field :nested %> 

這應該是足夠有nested屬性通過嵌套形式創建記事時設置。 未經測試。

+11

在Rails 3這個問題通過加入解決。見例如http://www.daokaous.com/rails3.0.0_doc/classes/ActiveRecord/Associations/ClassMethods.html#M001988「雙向關聯」部分下 – 2010-06-09 12:47:10

+2

我選擇禁用驗證時:id == nil 。因爲只有在編寫新的嵌套記錄時纔會發生這種情況,所以我希望這會很安全。奇怪的是,這個問題一直到2.3.8。 – aceofspades 2010-09-27 16:48:13

3

瑞安的解決方案實際上是真的很酷。 我去了,讓我的控制器變胖了,所以這個嵌套不會出現在視圖中。主要是因爲我的觀點有時候是json,所以我希望能夠儘可能少地在那裏脫身。

class Product < ActiveRecord::Base 
    has_many :notes 
    accepts_nested_attributes_for :note 
end 

class Note < ActiveRecord::Base 
    belongs_to :product 
    validates_presence_of :product_id unless :nested 
    attr_accessor :nested 
end 

class ProductController < ApplicationController 

def create 
    if params[:product][:note_attributes] 
     params[:product][:note_attributes].each { |attribute| 
      attribute.merge!({:nested => true}) 
    } 
    end 
    # all the regular create stuff here 
end 
end 
相關問題