2008-09-18 40 views
5

我有三個型號: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項目。

回答

6

看來您對has_one:through的使用是正確的。你看到的問題與保存對象有關。要使關聯工作,正在引用的對象需要有一個ID來填充該對象的model_id字段。在這種情況下,PackReleaseItems有一個pack_id和一個release_item_id字段,需要填寫該關聯才能正常工作。在通過關聯訪問對象之前嘗試保存。

+0

但是,如果我使用has_many:through,belongs_to或has_one,我不必先保存。 – lordscarlet 2008-09-18 11:29:56

+0

是的,這似乎已經照顧它。不過,我認爲我不需要與其他協會合作。 – lordscarlet 2008-09-18 11:47:43

2

你的問題在於你如何關聯ReleaseItemPack

has_many :throughhas_one :through都通過一個也充當聯接表的對象工作,在這種情況下,它是PackReleaseItem。因爲這不僅是一個連接表(如果是這樣,你應該只使用has_many沒有:through),正確地創建關聯需要創建的連接對象,像這樣:

>> item.pack_release_items.create :pack => pack 

你與你的item.pack = pack做什麼調用只是將內存中的對象關聯起來。當你再次查看時,它看起來是「throughpack_release_items,它是空的。

1

您想保存或創建(而不是新建)物品和包裝。否則,數據庫沒有爲該關聯分配ID。