2010-03-18 13 views
123

इस उदाहरण में, मैं user को profile के साथ बना देता हूं, फिर बाद में उस उपयोगकर्ता के लिए profile बनाते हैं। मैंने has_one एसोसिएशन के साथ निर्माण का उपयोग करने की कोशिश की लेकिन वह उड़ा। मैं इस काम को देखने का एकमात्र तरीका has_many का उपयोग कर रहा हूं। user केवल सबसे अधिक profile पर माना जाता है।रेल में हैसोन एसोसिएशन के साथ निर्माण का उपयोग

मैं इसे आजमा रहा हूं। मेरे पास है:

class User < ActiveRecord::Base 
    has_one :profile 
end 

class Profile < ActiveRecord::Base 
    belongs_to :user 
end 

लेकिन जब मैं कार्य करें:

user.build_profile 

मैं त्रुटि मिलती है:

ActiveRecord::StatementInvalid: Mysql::Error: Unknown column 'profiles.user_id' in 'where clause': SELECT * FROM `profiles` WHERE (`profiles`.user_id = 4) LIMIT 1 

वहाँ 0 या 1 संघ के लिए रेल में कोई तरीका है?

+0

वास्तव में क्या आप की कोशिश की थी? क्या आप कृपया कुछ कोड पोस्ट कर सकते हैं? –

उत्तर

324

ModelName.new(:owner => @owner) 

ही है build विधि हस्ताक्षर has_one और has_many संघों के लिए अलग है: अगर build काम नहीं कर रहा, तो आप सिर्फ new उपयोग कर सकते हैं।

class User < ActiveRecord::Base 
    has_one :profile 
    has_many :messages 
end 

has_many सहयोग के लिए निर्माण वाक्य रचना:

user.messages.build 

has_one सहयोग के लिए निर्माण वाक्य रचना:

user.build_profile # this will work 

user.profile.build # this will throw error 

अधिक जानकारी के लिए has_one संघ documentation पढ़ें।

+22

के साथ model_name बनाते हैं, has_one के लिए अलग वाक्यविन्यास हमेशा मुझे पकड़ता है ... Dammit! – Galaxy

+2

रोजमर्रा की नई (अजीब) जादू विधियों को सीखना ... – tackleberry

+0

@ टैकलेबेरी, इसे मेटाप्रोग्रामिंग –

-13

यह has_one होना चाहिए। के रूप में

@owner.model_names.build 
+10

यह वही नहीं है: यदि आप निर्माण के साथ एक नया मॉडल_नाम बनाते हैं, जब @owner सहेजा जाता है तो नया मॉडल_नाम भी सहेजा जाएगा। तो, आप एक माता-पिता और बच्चों को बनाने के लिए निर्माण का उपयोग कर सकते हैं जो एक साथ सहेजे जाएंगे। यह मामला नहीं है यदि आप .new –

16

त्रुटि संदेश पर एक अच्छा नज़र डालें। यह आपको बता रहा है कि प्रोफ़ाइल तालिका में आपके पास कॉलम user_id आवश्यक नहीं है। मॉडल में संबंध स्थापित करना केवल उत्तर का हिस्सा है।

आपको एक माइग्रेशन बनाने की भी आवश्यकता है जो प्रोफाइल तालिका में user_id कॉलम जोड़ता है। रेल उम्मीद करते हैं कि यह वहां होगा और यदि ऐसा नहीं है तो आप प्रोफ़ाइल तक नहीं पहुंच सकते हैं।

अधिक जानकारी के लिए इस लिंक पर एक नज़र डालें:

Association Basics

+0

मैंने अभी अपनी समस्या का पता लगाया। जिस पुस्तक से मैं सीख रहा हूं वह विदेशी कुंजी निर्माण को बहुत अच्छी तरह से समझा नहीं गया। मैंने एक नया माइग्रेशन बनाया जो मेरे मॉडल के लिए एक विदेशी कुंजी जोड़ता है। धन्यवाद। – espinet

+0

क्या आपको हर बार कॉलम बनाने की ज़रूरत है? मुझे यह विचार था कि यह स्वचालित रूप से हुआ। मुझे नहीं पता कि मुझे यह विचार कहां मिला। – Rimian

0

उपयोग के मामले के आधार पर यह विधि लपेट और स्वचालित रूप से संघ का निर्माण जब नहीं मिला करने के लिए सुविधाजनक हो सकता है।

old_profile = instance_method(:profile) 
define_method(:profile) do 
    old_profile.bind(self).call || build_profile 
end 

अब #profile विधि बुला संबद्ध प्रोफ़ाइल वापसी या एक नया उदाहरण का निर्माण या तो होगा।

स्रोत: When monkey patching a method, can you call the overridden method from the new implementation?

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