2011-12-23 15 views
12

नहीं मिल सका मैं निम्नलिखित कोड (कुछ सरल ...रेल: ActiveRecord :: HasManyThroughSourceAssociationNotFoundError: स्रोत संघ (रों)

create_table :signatures do |t| 
    t.integer :signer_id 
    t.integer :card_id 

    t.timestamps 
end 
मॉडल की तरह लग रही के साथ

... है

class Signature < ActiveRecord::Base 
    belongs_to :card 
    belongs_to :user 
end 

class Card < ActiveRecord::Base 
    has_many :signatures 
    has_many :signers, :through => :signatures, :foreign_key => "card_id" 
end 


class User < ActiveRecord::Base 

    has_many :sent_cards, :class_name => "Card", :foreign_key => "sender_id" 
    has_many :received_cards, :class_name => "Card", :foreign_key => "recipient_id" 

    has_many :signatures 
    has_many :signed_cards, :through => :signatures, :foreign_key => "signer_id" 

end 

मैं रेल कंसोल का उपयोग निम्न त्रुटि देखें ...

ruby-1.9.2-p0 > u15.signed_cards 
ActiveRecord::HasManyThroughSourceAssociationNotFoundError: Could not find the source association(s) :signed_card or :signed_cards in model Signature. Try 'has_many :signed_cards, :through => :signatures, :source => <name>'. Is it one of :card or :user? 
    from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.1.0/lib/active_record/reflection.rb:517:in `check_validity!' 
    from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.1.0/lib/active_record/associations/association.rb:27:in `initialize' 
    from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.1.0/lib/active_record/associations/collection_association.rb:24:in `initialize' 
    from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.1.0/lib/active_record/associations.rb:164:in `new' 
    from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.1.0/lib/active_record/associations.rb:164:in `association' 
    from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.1.0/lib/active_record/associations/builder/association.rb:41:in `block in define_readers' 
    from (irb):11 
    from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/railties-3.1.0/lib/rails/commands/console.rb:45:in `start' 
    from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/railties-3.1.0/lib/rails/commands/console.rb:8:in `start' 
    from /home/slabounty/.rvm/gems/ruby-1.9.2-p0/gems/railties-3.1.0/lib/rails/commands.rb:40:in `<top (required)>' 
    from script/rails:6:in `require' 
    from script/rails:6:in `<main>' 

मैं एक ही बात मिलता है जब मैं करता हूँ source => :card/:user जोड़ें (होना चाहिए: इस मामले में कार्ड मुझे विश्वास है)।

कोई विचार जो मैं यहां गलत कर रहा हूं?


एक आंशिक समाधान दिखा क्योंकि मैं एक कुछ चीजें साफ करने के लिए चाहता था। माइग्रेशन पिछले संस्करण के समान ही बना रहा। अब मैं एसक्यूएल त्रुटि देख रहा हूं (नीचे देखें) जहां यह हस्ताक्षर में user_id नहीं ढूंढ सकता है। I इसे कहने से नफरत है, लेकिन ज्यादातर मैं इसमें डाल रहा हूं: विदेशी_की whereever मुझे लगता है कि वे कोई फायदा नहीं उठा सकते हैं।

class Signature < ActiveRecord::Base 
     belongs_to :card 
     belongs_to :signer, :class_name => "User" 
    end 


    class Card < ActiveRecord::Base 
     # Correct 
     has_many :signatures 
     has_many :signers, :through => :signatures, :source => :user 

    end 

    class User < ActiveRecord::Base 
     # Wrong! 
     has_many :signatures, :foreign_key => "signer_id" 
     has_many :signed_cards, :through => :signatures, :source => :card 
    end 

त्रुटि (ऋण स्टैक ट्रेस) के साथ

ruby-1.9.2-p0 > u15.signed_cards 
    Card Load (0.5ms) SELECT "cards".* FROM "cards" INNER JOIN "signatures" ON "cards"."id" = "signatures"."card_id" WHERE "signatures"."user_id" = 15 ORDER BY cards.created_at DESC 
SQLite3::SQLException: no such column: signatures.user_id: SELECT "cards".* FROM "cards" INNER JOIN "signatures" ON "cards"."id" = "signatures"."card_id" WHERE "signatures"."user_id" = 15 ORDER BY cards.created_at DESC 
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: signatures.user_id: SELECT "cards".* FROM "cards" INNER JOIN "signatures" ON "cards"."id" = "signatures"."card_id" WHERE "signatures"."user_id" = 15 ORDER BY cards.created_at DESC 

Card.signers की उम्मीद के रूप में एक खाली सरणी देता है।

अभी भी इस पर कुछ मदद की तलाश है। मैं इस बारे में सरल, सीधा स्पष्टीकरण के तरीके में अधिक पता लगाने में सक्षम नहीं हूं, जहां आप एक ही नाम का उपयोग नहीं कर रहे हैं (यानी आपको एक विदेशी_की और स्रोत की आवश्यकता है।

उत्तर

9

उपयोगकर्ता इस तरह परिभाषित किया जाना चाहिए:

class User < ActiveRecord::Base 

    has_many :sent_cards, :class_name => "Card", :foreign_key => "sender_id" 
    has_many :received_cards, :class_name => "Card", :foreign_key => "recipient_id" 

    has_many :signatures 
    has_many :signed_cards, :through => :signatures, :source => :card 

end 

जब आपके सहयोग नाम पर इस्तेमाल किया नाम से अलग है: के माध्यम से आप स्रोत पैरामीटर परिभाषित करने के लिए है, तो आप अपवाद संदेश यह स्पष्ट रूप से लिए कहता है यह करने के लिए पर नज़र डालें तो।।

+0

ठीक है, कि परिवर्तन मैं निम्नलिखित (ऋण स्टैक ट्रेस) मिलता है ... माणिक 1.9.2-p0 साथ> u15.signed_cards कार्ड लोड (0.5ms) "कार्ड" का चयन करें। * "कार्ड से "इनर जॉइन" हस्ताक्षर "ऑन" कार्ड्स "।" आईडी "=" हस्ताक्षर "।" कार्ड_आईडी "कहां" हस्ताक्षर "।" User_id "= 15 कार्ड द्वारा आदेश .created_at डीईएससी SQLite3 :: SQLException: ऐसा कोई कॉलम नहीं: हस्ताक्षर। user_id: "कार्ड" चुनें। * "कार्ड" से "कार्ड" पर "हस्ताक्षर" जॉइन "आईडी" = "हस्ताक्षर"। "card_id" कहां "हस्ताक्षर"। "user_id" = 15 कार्ड द्वारा आदेश .created_at DESC – slabounty

+0

और बाकी की त्रुटि ... ActiveRecord :: स्टेटमेंट इन्वालिड: SQLite3 :: SQLException: ऐसा कोई कॉलम नहीं: signatures.user_id: "कार्ड" चुनें। * "कार्ड" से INNER "कार्ड" पर "हस्ताक्षर" में शामिल हों। " आईडी " = "हस्ताक्षर"। "card_id" कहां "हस्ताक्षर"। "user_id" = 15 कार्ड द्वारा आदेश दिया गया .created_at डीईएससी – slabounty

+0

@ स्लैबैंटी: has_many: हस्ताक्षरों को 'विदेशी_की =>: signer_id' की आवश्यकता है। यह उम्मीद है कि इस क्षेत्र को 'user_id' कहा जाएगा। –

5

ठीक है, क्योंकि मेरे पास इतना कठिन समय था, इसलिए मैं सभी को दिखाना चाहता था कि अंतिम संस्करण कैसा दिखता था। कारणों का एक अच्छा हिस्सा मेरे पास इतना कठिन समय था इसे बाहर निकालना, यह तथ्य था कि रेल कंसोल प्रतीत होता है जैसे मैंने बदलाव किए हैं। मुझे यह एहसास नहीं हुआ जब तक कि मैं एक रात को छोड़ दिया, अगली सुबह वापस आया और मामला था जो पिछली रात काम नहीं कर रहा था और जो मामला काम नहीं कर रहा था।

प्रवासन समान है, लेकिन मैं इसे पूर्णता के लिए दोहरा दूंगा।

def change 
    create_table :signatures do |t| 
     t.integer :signer_id 
     t.integer :card_id 
     t.boolean :signed, :default => false 
     t.text :message 

     t.timestamps 
    end 
end 

हस्ताक्षर वर्ग कार्ड मामले जा रहा है कि सामान्य रूप से उदाहरण और उपयोगकर्ता प्रकार के हस्ताक्षरकर्ता किया जा रहा है में दिखाया जाता है के साथ दो belongs_to है।

class Signature < ActiveRecord::Base 
    belongs_to :card 
    belongs_to :signer, :class_name => "User" 
end 

उपयोगकर्ता कई हस्ताक्षर (आवश्यक आप उन्हें सीधे का उपयोग नहीं करते हैं, भले ही) कार्ड का एक स्रोत के साथ हस्ताक्षर के माध्यम से एक dmany signed_cards (कह रेल जो वर्ग प्रकार signed_cards हैं।

class User < ActiveRecord::Base 
    has_many :signatures, :foreign_key => "signer_id" 
    has_many :signed_cards, :through => :signatures, :source => :card 
end 

अंत में, कार्ड कई हस्ताक्षर (एक बार फिर से आवश्यक) और कई हस्ताक्षरकर्ताओं हस्ताक्षर के माध्यम से और signer_id का हस्ताक्षरकर्ता के लिए foreign_key है।

class Card < ActiveRecord::Base 
    has_many :signatures 
    has_many :signers, :through => :signatures, :foreign_key => 'signer_id' 
end 

उम्मीद है कि इससे अन्य लोगों को समान समस्याएं मिलेंगी।

+1

रेल कंसोल आपके कोड में तब तक नहीं उठाता जब तक कि आप 'रीलोड' नहीं कहते हैं (और फिर भी यह उन चीजों को नहीं उठाएगा जो रत्नों या प्रारंभिक परिवर्तनों में बदलाव की तरह हैं) –

+0

@FrederickCheung धन्यवाद! मैंने सोचा कि यह रेल की तरह ही था जहां चीजें स्वचालित रूप से उठाई जाती हैं। – slabounty

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