2012-01-08 127 views
6

我有一個項目資源和一個所有者資源。如何創建引用現有嵌套屬性的新對象?

rails g scaffold Item name:string 
rails g scaffold Owner name:string 

class Item < ActiveRecord::Base 
    has_one :owner 
    accepts_nested_attributes_for :owner 
end 

class Owner < ActiveRecord::Base 
    belongs_to :item 
end 

我的問題是我無法創建一個引用現有所有者對象的新Item對象。

In /db/migrate/create_owners.rb 
def self.up 
    ... 
    t.integer :item_id 
end 

rake db:migrate 
rails c 

ruby-1.9.2-p0 > o= Owner.create(:name => "Test") 
=> #<Owner id: 1, name: "Test", created_at: "...", updated_at: "..."> 

ruby-1.9.2-p0 > i= Item.create(:owner_attributes => {"id" => Owner.last.id.to_s}) 
ActiveRecord::RecordNotFound: Couldn't find Owner with ID=1 for Item with ID= 

我知道Item.create(:owner_id => "1")會在這種情況下工作,但不幸的是這不是我的應用程序一個可行的解決方案。這是因爲我正在動態添加和刪除嵌套屬性,例如,需要創建一個具有一個現有Owner對象和一個新Owner對象的新Item對象。

我發現這些鏈接,但不能工作了,如果這是一個功能或在軌道中的錯誤:
https://rails.lighthouseapp.com/projects/8994/tickets/4254-assigning-nested-attributes-fails-for-new-object-when-id-is-specified
http://osdir.com/ml/RubyonRails:Core/2011-05/msg00001.html

有人可以給我一個想法,我怎樣才能使這項工作或我誤解了正確的方法來使用'accepted_nested_attributes_for'?

我使用Rails 3.0.5和Ruby 1.9.2p0。

在此先感謝。

回答

1

當您嘗試在嵌套屬性的所有者ID創建Item,它告訴ActiveRecord的更新現有Owner記錄。 ActiveRecord無法找到所有者記錄,因爲沒有現有外鍵值(項目記錄的id仍然爲零)。

Item.create(:owner_attributes => {"id" => Owner.last.id.to_s}) 
#=> ActiveRecord::RecordNotFound: Couldn't find Owner with ID=1 for Item with ID= 

嘗試交換has_one/belongs_to關聯,並將外鍵移動到項目表中。然後,您可以在父級(不是嵌套)模型中設置外鍵,並仍然使用嵌套屬性。

class Item < ActiveRecord::Base 
    belongs_to :owner 
    accepts_nested_attributes_for :owner 
end 

class Owner < ActiveRecord::Base 
    has_one :item 
end 

owner = Owner.create 

Item.create(:owner_id => owner.id, :owner_attributes => {"id" => owner.id, ...}) 
#=> Works!!! Note that the owner id is used twice. With some work you could probably set the id in one place or the other. 
+0

謝謝!我從未參與過這個項目一年多,但你的回答是有道理的。當我有一點時,我會嘗試(出於興趣)。 – 2014-01-21 09:48:52

0

accepts_nested_attributes_for僅用於has_onehas_many關聯。 (見http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html否belongs_to)它被稱爲'嵌套',所以沒有太多的幫助。也許重構你的應用程序?

具體來說,您遇到的錯誤情況是因爲它期望父應該能夠找到嵌套模型,給定嵌套模型的ID。即

parent.nested_model.find(id) 

它的存在似乎基本上從更新不屬於母公司

+0

謝謝。我將示例更改爲使用has_one。不幸的是,問題依然存在。有什麼方法可以實現我的嘗試,還是我最好回到製圖板? – 2012-01-08 11:14:37

+0

不是真的,它會爲belongs_to工作,那裏沒有一個例子。如果has_one有效,belongs_to也會起作用。 – 2012-01-08 12:02:34

+0

@RyanBigg嗯,我必須誤解如何嵌套的作品。如果has_one有效,ye'belongs_to'應該可以工作。 @Jack不,它看起來像燈塔鏈接的問題(https://rails.lighthouseapp.com/projects/8994/tickets/4254-assigning-nested-attributes-fails-for-new-object-when-id-是指定的#ticket-4254-6)。 – 2012-01-09 08:40:27

2

我解決了這個問題的另一種方式兒童模特停下,想萬一在這裏發表的是一個簡化版本,它幫助其他人。在我的真實應用程序中,兩個資源之間的關聯是HABTM,而嵌套資源是文件附件。

因此,在控制器的創建操作中,我將原始資源的參數和嵌套資源的參數分開。

然後,我進一步將嵌套的資源分爲存在於數據庫中的對象和不存在的對象,並將這些對象放入數組中。

如果沒有現有的嵌套對象存在,那麼從這裏開始就是一帆風順的。

然而,假定現有的和新的嵌套對象都存在,我創造這樣一個新的項目對象:
@item = Item.new(:attachment_ids => existing_attachment_ids)

之後,因此,我更新@item:
@item.update_attributes(original_item_params)
@item.update_attributes(params_for_new_nested_objects)

然後就可以調用@item.save並讓它在出現任何錯誤時重新呈現視圖。

如果這是一個錯誤或功能ir Rails,我仍然不能解決。如果有人對這個問題或我的解決方案有任何想法,我會很高興聽到他們。

+0

僅供參考,另請參閱舊的Rails票證:https://rails.lighthouseapp.com/projects/8994/tickets/4254-assigning-nested-attributes-fails-for-new-object-when-id-is-specified – 2014-07-28 20:56:53

相關問題