2012-08-03 14 views
8

ActiveRecord को समझने के लिए प्रतीत नहीं होता है कि, नेस्टेड विशेषताओं वाले मौजूदा रिकॉर्ड के लिए पैरा का एक सेट दिया गया है, यह एक नया नेस्टेड रिकॉर्ड बना सकता है जो स्वयं को नेस्टेड है मौजूदा रिकॉर्ड। (संबंध पेड़: Existing -> New -> Existing)AcitveRecord nested मौजूदा रिकॉर्ड्स

क्या यह एक बग है, या क्या मुझे कुछ याद आ रही है?

मुझे आपको एक साधारण उदाहरण दिखाएं।

यहाँ मेरी मॉडल हैं:

class User < ActiveRecord::Base 
    has_many :posts 
    attr_accessible :name, :posts_attributes 
    accepts_nested_attributes_for :posts 
end 

class Post < ActiveRecord::Base 
    belongs_to :group 
    belongs_to :user 
    attr_accessible :content, :title, :group_attributes 
    accepts_nested_attributes_for :group 
end 

class Group < ActiveRecord::Base 
    has_many :posts 
    attr_accessible :name 
end 

मैं प्रत्येक तालिका में एक रिकॉर्ड बनाया है, और तदनुसार उन्हें संबंधित है, इसलिए प्रत्येक मेज एक id=1 --This में जाना जाता है के साथ उस में एक रिकॉर्ड है। अब, मैं एक मौजूदा उपयोगकर्ता, एक नया पोस्ट, और एक मौजूदा समूह, है और accepts_nested_attributes_for का उपयोग कर कि रिकॉर्ड को अपडेट करने का प्रयास करें, यह यह पसंद नहीं करता:

1.9.3-p125 :044 > params 
{ 
        :id => 1, 
       :name => "Billy", 
    :posts_attributes => [ 
     [0] { 
          :title => "Title", 
         :content => "Some magnificent content for you!", 
      :group_attributes => { 
        :id => 1, 
       :name => "Group 1" 
      } 
     } 
    ] 
} 
1.9.3-p125 :045 > u 
#<User:0x00000002f7f380> { 
      :id => 1, 
      :name => "Billy", 
    :created_at => Fri, 03 Aug 2012 20:21:37 UTC +00:00, 
    :updated_at => Fri, 03 Aug 2012 20:21:37 UTC +00:00 
} 
1.9.3-p125 :046 > u.update_attributes params 
    (0.1ms) begin transaction 
    (0.1ms) rollback transaction 
ActiveRecord::RecordNotFound: Couldn't find Group with ID=1 for Post with ID= 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/nested_attributes.rb:462:in `raise_nested_attributes_record_not_found' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/nested_attributes.rb:332:in `assign_nested_attributes_for_one_to_one_association' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/nested_attributes.rb:288:in `group_attributes=' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/attribute_assignment.rb:94:in `block in assign_attributes' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/attribute_assignment.rb:93:in `each' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/attribute_assignment.rb:93:in `assign_attributes' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/base.rb:498:in `initialize' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/reflection.rb:183:in `new' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/reflection.rb:183:in `build_association' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/associations/association.rb:233:in `build_record' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/associations/collection_association.rb:112:in `build' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/nested_attributes.rb:405:in `block in assign_nested_attributes_for_collection_association' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/nested_attributes.rb:400:in `each' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/nested_attributes.rb:400:in `assign_nested_attributes_for_collection_association' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/nested_attributes.rb:288:in `posts_attributes=' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/attribute_assignment.rb:85:in `block in assign_attributes' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/attribute_assignment.rb:78:in `each' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/attribute_assignment.rb:78:in `assign_attributes' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/persistence.rb:216:in `block in update_attributes' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/transactions.rb:295:in `block in with_transaction_returning_status' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/transactions.rb:208:in `transaction' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/transactions.rb:293:in `with_transaction_returning_status' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.7/lib/active_record/persistence.rb:215:in `update_attributes' 
    from (irb):15 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.7/lib/rails/commands/console.rb:47:in `start' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.7/lib/rails/commands/console.rb:8:in `start' 
    from /home/trevor/.rvm/gems/ruby-1.9.3-p125/gems/railties-3.2.7/lib/rails/commands.rb:41:in `<top (required)>' 
    from script/rails:6:in `require' 
    from script/rails:6:in `<main>'1.9.3-p125 :047 > 

यह सोचता है कि यह एक समूह नहीं मिल सकता है (एक ज्ञात आईडी के साथ), एक नई पोस्ट से संबंधित। यह काम करता है जब मैं group_attributes से आईडी हटाता हूं (लेकिन यह एक नया समूह रिकॉर्ड बनाता है)। यह काम करता है जब मैं posts_attributes एक आईडी देता हूं, और group_attributes से आईडी हटा देता हूं (और फिर एक नया समूह बनाता है)। यह तब भी काम करता है जब उनके पास आईडी हों।

संबंध काम कर रहा है:

1.9.3-p125 :059 > p = Post.new({ group_attributes: { name: 'Testing' } }) 
#<Post:0x00000004212380> { 
      :id => nil, 
     :title => nil, 
     :content => nil, 
     :group_id => nil, 
     :user_id => nil, 
    :created_at => nil, 
    :updated_at => nil 
} 
1.9.3-p125 :060 > p.group 
[ 
    [0] #<Group:0x00000004211868> { 
       :id => nil, 
       :name => "Testing", 
     :created_at => nil, 
     :updated_at => nil 
    } 
] 

यह भी पूरी तरह से जब User निर्माण के दौरान posts_attributes और group_attributes का उपयोग कर, अगर रिकॉर्ड के सभी नए हैं काम करता है।

क्या यह अभी भी पहले उदाहरण में काम नहीं करना चाहिए? ActiveRecord यह समझने के लिए पर्याप्त स्मार्ट होना चाहिए ...!

+0

आप उपयोगकर्ता मॉडल में 'has_many: टिप्पणियां' खो रहे हैं। – jordanpg

+0

ओह, ठीक है अभी भी मुद्दा खड़ा है। :) मैं उदाहरण को सरल बना दूंगा। – wulftone

+0

लंबे सवाल, लेकिन एक नए रिकॉर्ड के साथ मौजूदा संबंध कैसे है? – pjammer

उत्तर

4

मुझे लगता है कि यह क्या हो रहा है: आप समूह के लिए एक आईडी में गुजर रहे हैं, जो कि समूह के सक्रिय ActiveCecord को इंगित करता है। ActiveRecord उस समूह को group_attributes में आपके अन्य डेटा के साथ अपडेट करने का प्रयास कर रहा है। आप इस अंदर post_attributes कर रहे हैं के बाद से, ActiveRecord संघपद और समूह के बीच के माध्यम से उस समूह खोजने की कोशिश कर रहा है। यही है, ActiveRecord पहले संबंधित समूह की तलाश करता है - जहां id = post.group_id - तब उस परिणाम से आईडी = 1 के साथ एक दिखता है। यह आपके मामले में, जैसा कि माता-पिता के रिश्ते के लिए थोड़ा अजीब और बेवकूफ लग सकता है, लेकिन मुझे यकीन है कि आप देख सकते हैं कि यह दूसरी दिशा में जाने पर उपयोगी व्यवहार है, जहां घोंसला वाले गुण संभावित रूप से कई बच्चों में से एक या अधिक का प्रतिनिधित्व करते हैं।

हालांकि, post_attributes में डेटा से बनाई गई आपकी पोस्ट ऑब्जेक्ट अभी तक किसी समूह से संबद्ध नहीं है - post.group_id शून्य है। इसलिए, जब ActiveRecord उस समूह को प्राप्त करने के लिए पहली खोज करता है, तो यह खाली हो जाता है। इसके अनुरूप, इसे (खाली) परिणामों में आईडी = 1 वाला समूह नहीं मिला है। तकनीकी रूप से, रिकॉर्ड वहां है, लेकिन पोस्ट के साथ संबंध के संदर्भ में नहीं है।

आप post_attributes में group_id => 1 सहित इसे साबित कर सकते हैं।मेरा मानना ​​है कि यदि आप ऐसा करते हैं, तो ActiveRecord समूह द्वारा एसोसिएशन द्वारा समूह को खोजेगा, फिर परिणामों के आईडी = 1 के साथ समूह को सफलतापूर्वक चुनें, फिर उस समूह को group_attributes में अतिरिक्त डेटा के साथ अपडेट करें।

यह भी ध्यान दें कि केवल को पोस्ट के अंदर समूह के लिए नेस्टेड विशेषताओं को शामिल करने का कारण यह है कि यदि आप उपयोगकर्ता को समूह नाम को अपडेट करने की अनुमति दे रहे हैं, तो वे एक नई पोस्ट बना रहे हैं। यदि आप जो भी करना चाहते हैं, वह मौजूदा समूह में नई पोस्ट को लिंक कर रहा है, तो आपको post_attributes में group_id को शामिल करने की आवश्यकता है और आप group_attributes से छुटकारा पा सकते हैं।

+0

यह मेरे लिए बहुत तार्किक लगता है, लेकिन यह परिदृश्य लंबे समय से चला गया है। :) मुझे याद है कि मैं _did_ एसोसिएशन और रूट रिकॉर्ड पर एक साथ गुण अपडेट करना चाहता हूं (मैं इन सटीक उपयोगकर्ता, पोस्ट और समूह तालिकाओं का उपयोग नहीं कर रहा था, लेकिन यह एक समान संरचना थी)। मेरा मानना ​​है कि इस तरह की कार्रवाई करने की आवश्यकता भविष्य के कार्यान्वयन के लिए बैक-बर्नर पर रखी गई थी, फिर भूल गई। यह हमें वापस लेने के लिए वापस आ सकता है! आपके उत्तर के लिए धन्यवाद। जब मैं इसे फिर से चलाता हूं तो मैं इसका उल्लेख करूँगा। – wulftone

+0

इसे दोबारा कोशिश कर रहा है, मुझे 'पोस्ट'' में 'group_id' होने पर भी नए समूह' बनाए गए हैं - हालांकि यह कोई त्रुटि नहीं फेंकता है। यह सिर्फ 'group_id' को अनदेखा करता है और वैसे भी बनाता है। अभी भी ऐसा प्रतीत नहीं होता है। – wulftone

+0

दमित। वास्तव में सोचा था कि मेरे पास एक नाखून था। मुझे इस सप्ताह के अंत में परिदृश्य के साथ खेलने के लिए कुछ समय लगेगा और देखें कि मैं किसके साथ आ सकता हूं, यह अब मेरे साथ फंस गया है। ;) – Yardboy

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