如何创建引用现有嵌套属性的新对象?

Jam*_*ard 6 ruby-on-rails nested-attributes

我有一个Item资源和一个Owner资源.

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
Run Code Online (Sandbox Code Playgroud)

我的问题是我无法创建引用现有Owner对象的新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=
Run Code Online (Sandbox Code Playgroud)

我知道这Item.create(:owner_id => "1")可以在这种情况下工作,但不幸的是,这在我的应用程序中不是一个可行的解决方案.这是因为我正在动态添加和删除嵌套属性,例如,需要使用一个现有的Owner对象和一个新的Owner对象创建一个新的Item对象.

我找到了这些链接,但如果这是一个功能或rails中的错误,则无法解决:
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

有人可以给我一个关于如何使这项工作或我误解了使用'accepts_nested_attributes_for'的正确方法的想法吗?

我使用的是Rails 3.0.5和Ruby 1.9.2p0.

提前致谢.

Wiz*_*Ogz 2

当您尝试在嵌套属性中创建Item具有所有者 ID 的记录时,它会告诉 ActiveRecord 更新现有Owner记录。ActiveRecord 无法找到 Owner 记录,因为不存在现有的外键值(项目记录的 id 仍然为 nil)。

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

尝试交换 has_one/belongs_to 关联并将外键移至 items 表。然后,您可以在父(非嵌套)模型中设置外键,并仍然使用嵌套属性。

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.
Run Code Online (Sandbox Code Playgroud)