"संदर्भ" माइग्रेशन में कॉलम नाम निर्दिष्ट करना


124

मैं एक migrationऔर तालिका का संदर्भ देते हुए रेल में एक बनाना चाहता हूं । आमतौर पर, मैं कुछ ऐसा करूंगा:

add_column :post, :user, :references

यह तालिका user_idमें नाम का एक कॉलम बनाता है posts। लेकिन क्या होगा, अगर इसके बजाय user_id, मुझे कुछ पसंद है author_id? मैं उसे कैसे कर सकता हूँ?

जवाबों:


59

इसे मैन्युअल रूप से करें:

add_column :post, :author_id, :integer

लेकिन अब, जब आप מ_to स्टेटमेंट बनाते हैं, तो आपको इसे संशोधित करना होगा, इसलिए अब आपको कॉल करना होगा

def post
    belongs_to :user, :foreign_key => 'author_id'
end

1
क्या मुझे कोई सूचकांक नहीं जोड़ना है?
caarlos0

1
हां, आपको माइग्रेशन में एक इंडेक्स बनाने की आवश्यकता होगी।
टॉम हैरिसन

1
रेल धोखा देती है - यह वास्तव में डिफ़ॉल्ट रूप से अनुक्रमित का उपयोग नहीं करता है। अब यदि आप अनुक्रमित चाहते हैं (जो एक महान विचार हैं - इस तथ्य के बावजूद कि रेल पूरी तरह से उन्हें अनदेखा कर देगा), तो आप निश्चित रूप से उन्हें जोड़ सकते हैं। आप सामान्य रूप से माइग्रेशन के बारे में अधिक जानकारी के लिए गाइड I लिंक को देखना चाहेंगे, और आप सीधे अपने माइग्रेशन में SQL कोड को कॉल करना भी समाप्त कर सकते हैं। मैं कहूंगा कि इसे अनदेखा करें, क्योंकि यह रेल का सामान्य हिस्सा नहीं है, आपको इसमें से 0 प्रदर्शन मिलेंगे, क्योंकि रेल के डिफ़ॉल्ट उत्पन्न SQL प्रश्न इसका कोई लाभ नहीं उठाते हैं। लिंक
एमएसचुल्ट्ज़

हम्म समझ गए। आपका बहुत बहुत धन्यवाद!
caarlos0

schema_plusमणि का उपयोग करते हुए , t.references :category, index: true, foreign_key: true, references: :match_categoriesमाइग्रेशन फ़ाइल में भी मेरे लिए काम किया।
एलक्विमिस्टा

251

रेल के लिए 5+

प्रारंभिक परिभाषा:

यदि आप अपनी Postमॉडल तालिका को परिभाषित कर रहे हैं , तो आप सेट कर सकते हैं references, indexऔर foreign_keyएक पंक्ति में:

t.references :author, index: true, foreign_key: { to_table: :users }

मौजूदा को अद्यतन करे:

यदि आप किसी मौजूदा तालिका में संदर्भ जोड़ रहे हैं, तो आप यह कर सकते हैं:

add_reference :posts, :author, foreign_key: { to_table: :users }

नोट: डिफ़ॉल्ट मान indexसत्य है।


क्या प्रारंभिक परिभाषा नल की अनुमति देगी? यदि नहीं, तो क्या आप अशक्त विकल्प जानते हैं?
वोरपुलस लीफेन

5
यह परिभाषा nullएस अनुमति देती है । उन्हें अनुमति नहीं देने के लिए, सामान्य विकल्प जोड़ें null: false
Ashitaka

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

धन्यवाद, यह वही है जिसकी मुझे तलाश थी!
फिलिप बी।

250

में रेल 4.2+ आप भी सेट कर सकते हैं विदेशी कुंजी DB में रूप में अच्छी तरह, जो एक बहुत अच्छा विचार है

साधारण संघों के लिए इसे t.referencesजोड़ने पर भी किया जा सकता है foreign_key: true, लेकिन इस मामले में आपको दो लाइनों की आवश्यकता होगी।

# The migration
add_reference :posts, :author, index: true
add_foreign_key :posts, :users, column: :author_id

# The model
belongs_to :author, class_name: "User"

2
धन्यवाद, लेकिन इस सवाल को टैग किया गया है Rails3, मैं सिर्फ मदद करने के लिए खुश हूँ
पारिस्थितिक

2
ऊह, मैंने उस पर ध्यान नहीं दिया। खैर, यह बहुत उपयोगी रहा है। :)
bon

2
जब मैंने यह देखा तो मैंने लगभग उम्मीद छोड़ दी थी! शुक्रिया @ecoologic!
डैन विलियम्स

2
@ecoologic, केवल एक चीज जिसे आप जोड़ना चाहते हैं, add_foreign_key केवल रेल है 4.2+। ;)
डैन विलियम्स

4
मुझे यकीन नहीं है कि आपको कॉल references: :usersमें विकल्प की आवश्यकता है add_reference। मैं इसे डॉक्स में प्रलेखित नहीं देखता हूं और इसके बिना यह मेरे अंत में काम करता है।
२२

87

रेल 4 में, जब पोस्टग्रैस्कल और स्कीमा_प्लस मणि का उपयोग कर आप लिख सकते हैं

add_reference :posts, :author, references: :users

यह एक कॉलम बनाएगा author_id, जो सही तरीके से संदर्भित करता है users(id)

और आपके मॉडल में, आप लिखते हैं

belongs_to :author, class_name: "User"

ध्यान दें, एक नई तालिका बनाते समय आप इसे इस प्रकार लिख सकते हैं:

create_table :things do |t| 
  t.belongs_to :author, references: :users 
end 

नोट: schema_plusयह संपूर्ण रूप से मणि रेल 5+ के साथ संगत नहीं है, लेकिन यह कार्यक्षमता मणि स्कीमा_आटो_साइन_सिग्नस ( स्कीमा_प्लस का हिस्सा) द्वारा प्रस्तुत की जाती है जो रेल 5 के साथ संगत है।


28
और यदि आप उपयोग कर रहे हैं create_table:t.references :author, references: :users
माइकल रेडियोनोव

2
अपने जवाब के लिए @ माइकलरेडियनोव की टिप्पणी को जोड़ना सही होगा।
टोक्साक

2
मैं रेल 4.1 स्रोत को देख रहा हूं, और मुझे ऐसा कोई प्रमाण नहीं मिला है जो :referencesवास्तव में कुछ भी करता हो।
jes5199 5

1
हां, आप सही हैं, मैं schema_plusउम्र के लिए मणि का उपयोग कर रहा हूं , और यह वास्तव में उस कार्यक्षमता को जोड़ रहा है। मैंने उसी के अनुसार अपना उत्तर संपादित किया।
नथ्नवाड़ा

2
रेल 6 में, ऐसा लगता है कि t.references :col_name, references: other_table_nameअतिरिक्त रत्नों को स्थापित किए बिना वाक्य रचना काम करती है।
Qqwy

51

यदि आप एक विदेशी कुंजी का उपयोग नहीं कर रहे हैं, तो इससे कोई फर्क नहीं पड़ता कि दूसरी तालिका का वास्तविक तालिका नाम क्या है।

add_reference :posts, :author

रेल 5 के रूप में , यदि आप एक विदेशी कुंजी का उपयोग कर रहे हैं, तो आप विदेशी कुंजी विकल्पों में अन्य तालिका का नाम निर्दिष्ट कर सकते हैं। ( चर्चा के लिए देखें https://github.com/rails/rails/issues/21563 )

add_reference :posts, :author, foreign_key: {to_table: :users}

रेल 5 से पहले, आपको विदेशी कुंजी को एक अलग चरण के रूप में जोड़ना चाहिए:

add_foreign_key :posts, :users, column: :author_id

12
to_table बहुवचन है:{to_table: :users}
hoffmanc

-3

alias_attribute (new_name, old_name) बहुत उपयोगी है। बस अपना मॉडल और संबंध बनाएं:

rails g model Post title user:references

फिर मॉडल को संपादित करें और साथ एक विशेषता उपनाम जोड़ें

alias_attribute :author, :user

उसके बाद आप चीजों को चलाने में सक्षम होंगे

Post.new(title: 'My beautiful story', author: User.first)

1
यह तब काम नहीं करता है जब आपको किसी अन्य मॉडल के कई संदर्भों को परिभाषित करने की आवश्यकता होती है, उदाहरण के लिए, पोस्ट (लेखक, संपादक)
ultrajohn
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.