2008-09-18 8 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 

समस्या यह है कि, निष्पादन के दौरान, अगर मैं रिलीज_इटम में एक पैक जोड़ता हूं तो यह पता नहीं है कि पैक एक पैक है। उदाहरण के लिए:

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 तक पहुंच प्राप्त करनी चाहिए, लेकिन यह अनजान है कि पैक एक पैक आइटम है।

उत्तर

6

ऐसा प्रतीत होता है कि has_one का आपका उपयोग सही है। आप जो समस्या देख रहे हैं उसे सहेजने वाली वस्तुओं के साथ करना है। काम करने के लिए एक संगठन के लिए, जिस वस्तु को संदर्भित किया जा रहा है उसे ऑब्जेक्ट के लिए model_id फ़ील्ड को पॉप्युलेट करने की आवश्यकता है। इस मामले में, PackReleaseItems में pack_id और release_item_id फ़ील्ड है जो एसोसिएशन के लिए सही ढंग से काम करने के लिए भरने की आवश्यकता है। एक एसोसिएशन के माध्यम से वस्तुओं तक पहुंचने से पहले बचत करने का प्रयास करें।

+0

लेकिन अगर मैं has_many का उपयोग करता हूं: through, belong_to, या has_one, मुझे पहले सहेजने की ज़रूरत नहीं है। – lordscarlet

+0

हाँ, ऐसा लगता है कि इसका ख्याल रखा गया है। मुझे नहीं लगता कि मुझे अन्य संगठनों के साथ ऐसा करना है, हालांकि। – lordscarlet

+0

क्या इसका ख्याल रखना है? क्या आप अपने इंटरैक्टिव कंसोल सत्र की एक क्लिप पोस्ट कर सकते हैं? मैंने रेल 2.1.0 का उपयोग करके थोड़ा परीक्षण आवेदन किया और यहां तक ​​कि पहले से ही बचत की स्थिति में मदद नहीं की, इसलिए मैंने अपना जवाब सबमिट कर दिया। –

2

आपकी समस्या यह है कि आप ReleaseItem और Pack से कैसे जुड़ रहे हैं।

has_many :through और has_one :through दोनों एक ऑब्जेक्ट के माध्यम से काम करते हैं जो इस मामले में PackReleaseItem में शामिल होने वाली तालिका के रूप में कार्य करता है। चूंकि यह नहीं है सिर्फ एक मेज में शामिल होने के (अगर यह थे, तो आप सिर्फ :through बिना has_many का उपयोग करना चाहिए), ठीक से, बनाने इसलिए की तरह संघ वस्तु में शामिल होने बनाने की आवश्यकता है:

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

क्या आप अपने item.pack = pack साथ क्या कर रहे कॉल बस वस्तुओं को स्मृति में जोड़ रहा है। जब आप इसे फिर से देखने के लिए जाते हैं, तो यह through "pack_release_items दिखाई देता है, जो खाली है।

+0

>> item.pack_release_items.create: pack => पैक => # >> item.pack => शून्य – lordscarlet

+0

ऐसा हो सकता है क्योंकि पैक सभी वैधताओं को संतुष्ट नहीं करता था। जब मैं घर आता हूं तो मैं इसे फिर से कोशिश करूंगा। – lordscarlet

+0

पैक आपके उदाहरण में ऊपर शून्य है क्योंकि पैक सहेजा नहीं गया है - आप अपने packReleaseItem में "pack_id: nil" देख सकते हैं। –

1

आप आइटम और पैक को सहेजना या बनाना चाहते हैं (नए की बजाय)। अन्यथा, डेटाबेस ने एसोसिएशन के लिए आईडी असाइन नहीं किया है।

संबंधित मुद्दे