has_one:通过工作如何?
问题描述:
我有三个型号:has_one:通过工作如何?
class ReleaseItem < ActiveRecord::Base
has_many :pack_release_items
has_one :pack, :through => :pack_release_items
end
class Pack < ActiveRecord::Base
has_many :pack_release_items
has_many :release_items, :through=>:pack_release_items
end
class PackReleaseItem < ActiveRecord::Base
belongs_to :pack
belongs_to :release_item
end
的问题是,在执行过程中,如果我一包添加到release_item它是不知道该包是包。例如:
Loading development environment (Rails 2.1.0)
>> item = ReleaseItem.new(:filename=>'MAESTRO.TXT')
=> #<ReleaseItem id: nil, filename: "MAESTRO.TXT", created_by: nil, title: nil, sauce_author: nil, sauce_group: nil, sauce_comment: nil, filedate: nil, filesize: nil, created_at: nil, updated_at: nil, content: nil>
>> pack = Pack.new(:filename=>'legion01.zip', :year=>1998)
=> #<Pack id: nil, filename: "legion01.zip", created_by: nil, filesize: nil, items: nil, year: 1998, month: nil, filedate: nil, created_at: nil, updated_at: nil>
>> item.pack = pack
=> #<Pack id: nil, filename: "legion01.zip", created_by: nil, filesize: nil, items: nil, year: 1998, month: nil, filedate: nil, created_at: nil, updated_at: nil>
>> item.pack.filename
NoMethodError: undefined method `filename' for #<Class:0x2196318>
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/base.rb:1667:in `method_missing_without_paginate'
from /usr/local/lib/ruby/gems/1.8/gems/mislav-will_paginate-2.3.3/lib/will_paginate/finder.rb:164:in `method_missing'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/associations/association_collection.rb:285:in `send'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/associations/association_collection.rb:285:in `method_missing_without_paginate'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/base.rb:1852:in `with_scope'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/associations/association_proxy.rb:168:in `send'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/associations/association_proxy.rb:168:in `with_scope'
from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/associations/association_collection.rb:281:in `method_missing_without_paginate'
from /usr/local/lib/ruby/gems/1.8/gems/mislav-will_paginate-2.3.3/lib/will_paginate/finder.rb:164:in `method_missing'
from (irb):5
>>
看来我应该可以访问item.pack,但它并不知道该包是一个Pack项目。
答
看来您对has_one:through的使用是正确的。你看到的问题与保存对象有关。要使关联工作,正在引用的对象需要有一个ID来填充该对象的model_id
字段。在这种情况下,PackReleaseItems
有一个pack_id
和一个release_item_id
字段,需要填写该关联才能正常工作。在通过关联访问对象之前尝试保存。
答
你的问题在于你如何关联ReleaseItem
和Pack
。
has_many :through
和has_one :through
都通过一个也充当联接表的对象工作,在这种情况下,它是PackReleaseItem
。因为这不仅是一个连接表(如果是这样,你应该只使用has_many
没有:through
),正确地创建关联需要创建的连接对象,像这样:
>> item.pack_release_items.create :pack => pack
你与你的item.pack = pack
做什么调用只是将内存中的对象关联起来。当你再次查看时,它看起来是“through
”pack_release_items
,它是空的。
答
您想保存或创建(而不是新建)物品和包装。否则,数据库没有为该关联分配ID。
但是,如果我使用has_many:through,belongs_to或has_one,我不必先保存。 – lordscarlet 2008-09-18 11:29:56
是的,这似乎已经照顾它。不过,我认为我不需要与其他协会合作。 – lordscarlet 2008-09-18 11:47:43