2008-09-18 17 views
5

Üç modelim var:Has_one: nasıl çalışır?

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 

Sorun şu ki, yürütme sırasında, bir release_item'e bir paket eklerseniz paketin bir paket olduğunu bilmiyor. Örneğin:

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 
>> 

Öyle görünüyor ki, item.pack'e erişmem gerekiyor, ancak paketin bir Pack öğesi olduğunun farkında değil.

cevap

6

Görünüşe göre has_one: through kullanımınız doğru. Gördüğünüz problem, nesneleri kaydetme ile ilgilidir. Bir ilişkilendirmenin çalışması için başvurulan nesnenin, nesne için model_id alanını doldurmak için bir kimliği olması gerekir. Bu durumda, PackReleaseItems, ilişkilendirmenin düzgün çalışması için doldurulması gereken pack_id ve release_item_id alanına sahiptir. Bir ilişkilendirme aracılığıyla nesnelere erişmeden önce kaydetmeyi deneyin.

+0

Ancak has_many: through, belongs_to veya has_one kullanıyorsam, önce kaydetmem gerekmiyor. – lordscarlet

+0

Evet, bununla ilgilenmiş görünüyor. Bunu diğer derneklerle yapmak zorunda olduğumu düşünmüyorum. – lordscarlet

+0

Bu işe yarar mı? Etkileşimli konsol oturumunuzun bir klibini yayınlayabilir misiniz? Rails 2.1.0 kullanarak küçük bir test uygulaması yaptım ve hatta önceden kaydetme bile duruma yardımcı olmadı, bu yüzden cevabımı sundum. –

2

Sorununuz, ReleaseItem ve Pack ile ilişkilendirme şeklinizdir.

has_many :through ve has_one :through ikisi de bu durumda PackReleaseItem içinde, bir birleştirme tablosu olarak hareket eden bir nesne üzerinden çalışır. Eğer item.pack = pack ile

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

yapıyoruz? Bu olmadığı için sadece düzgün, dernek nesne katılmak oluşturarak gerektirir oluştururken şöyle, (Öyle olsaydı, sadece :through olmadan has_many kullanmalıdır) birleşim tablosu çağrı sadece nesneleri hafızada birleştirmektir. Tekrar bakmaya gittiğinizde, boş olan "through" pack_release_items görünüyor.

+0

>> item.pack_release_items.create: pack => pack => # >> item.pack => nil – lordscarlet

+0

Bu, paketin tüm doğrulayıcıları tatmin etmediğinden oluşmuş olabilir. Eve gittiğimde tekrar deneyeceğim. – lordscarlet

+0

Paket, Paket kaydedilmemiş olduğu için örneğinizde sıfırdır - PackReleaseItem öğesinde "pack_id: nil" ifadesini görebilirsiniz. –

1

Öğeyi ve paketi (yeni yerine) kaydetmek veya oluşturmak istiyorsunuz. Aksi halde, veritabanı dernek için kimlik atamamıştır.