उपयोगकर्ता का उपयोग करके मॉडल उत्पन्न करें: उपयोगकर्ता बनाम संदर्भ_आईडी: पूर्णांक


176

मैं कैसे एक मॉडल है कि दूसरे मॉडल से संबंधित है उत्पन्न करने पर उलझन में हूँ। मेरी पुस्तक इस वाक्यविन्यास का उपयोग उपयोगकर्ता के साथ माइक्रोप्रोस्ट को जोड़ने के लिए करती है:

rails generate model Micropost user_id:integer

लेकिन http://guides.rubyonrails.org/ ऐसा करने के लिए कहता है:

rails generate model Micropost user:references

इन 2 द्वारा उत्पन्न माइग्रेशन अलग हैं। इसके अलावा, पूर्व के लिए, रेल कैसे जानता है कि user_idएक विदेशी कुंजी संदर्भित है user? धन्यवाद!

जवाबों:


190

जब आप माइग्रेशन चलाते हैं तो दोनों समान कॉलम जेनरेट करेंगे। रेल कंसोल में, आप देख सकते हैं कि यह मामला है:

:001 > Micropost
=> Micropost(id: integer, user_id: integer, created_at: datetime, updated_at: datetime)

दूसरा आदेश belongs_to :userआपके माइक्रोप्रोस्ट मॉडल में एक संबंध जोड़ता है जबकि पहला नहीं है। जब यह संबंध निर्दिष्ट किया जाता है, तो ActiveRecord यह मान लेगा कि विदेशी कुंजी को user_idकॉलम में रखा गया है और यह Userविशिष्ट उपयोगकर्ता को इंस्टेंट करने के लिए नामित मॉडल का उपयोग करेगा ।

दूसरा कमांड नए user_idकॉलम पर एक इंडेक्स भी जोड़ता है ।


1
क्या दो तालिकाओं के संदर्भ के साथ एक मॉडल उत्पन्न करना संभव है
praveenkumar

ध्यान दें कि यह अन्य मॉडल (उपयोगकर्ता) पर एक has_many एसोसिएशन नहीं जोड़ता है, जिसे आप भी जोड़ना चाह सकते हैं।
Sv1

45

कैसे पता चलता user_idहै कि एक विदेशी कुंजी संदर्भित है user?

रेल खुद नहीं जानती कि user_idयह एक विदेशी कुंजी है user। पहले कमांड में rails generate model Micropost user_id:integerयह केवल एक कॉलम जोड़ता है, user_idहालांकि रेल्स कॉल के उपयोग को नहीं जानता है। आपको मैन्युअल रूप से Micropostमॉडल में लाइन डालने की आवश्यकता है

class Micropost < ActiveRecord::Base
  belongs_to :user
end

class User < ActiveRecord::Base
  has_many :microposts
end

कीवर्ड belongs_toऔर has_manyइन मॉडलों के बीच संबंध निर्धारित करते हैं और मॉडल के लिए user_idएक विदेशी कुंजी घोषित करते हैं User

बाद की कमांड मॉडल में rails generate model Micropost user:referencesलाइन जोड़ती है और इसके द्वारा एक विदेशी कुंजी के रूप में घोषित की जाती है।belongs_to :userMicropost

FYI
पूर्व विधियों का उपयोग करके विदेशी कुंजियों की घोषणा करने से केवल रेल्स को मॉडल / तालिकाओं के संबंध के बारे में पता चलता है। डेटाबेस रिश्ते के बारे में अज्ञात है। इसलिए जब आप सॉफ्टवेयर का उपयोग करके ईईआर डायग्राम बनाते हैं, जैसे MySql Workbenchआप पाते हैं कि मॉडलों के बीच कोई रिश्ता नहीं है। निम्नलिखित चित्र में पसंद है यहां छवि विवरण दर्ज करें

हालाँकि, यदि आप बाद की विधि का उपयोग करते हैं, तो आप पाते हैं कि आप माइग्रेशन फ़ाइल की तरह दिखते हैं:

def change
    create_table :microposts do |t|
      t.references :user, index: true

      t.timestamps null: false
    end
    add_foreign_key :microposts, :users

अब विदेशी कुंजी डेटाबेस स्तर पर सेट की गई है। और आप उचित EERआरेख उत्पन्न कर सकते हैं । यहां छवि विवरण दर्ज करें


1
ऐसा लगता है कि नवीनतम रेल जनरेटर ने add_foreign_keyकार्रवाई foreign_key: trueको t.referencesलाइन के विकल्प के साथ बदल दिया , जिसका अर्थ है index: true। तो यह अब है t.references :user, foreign_key: true। वर्तमान में foreign_keyउपलब्ध विकल्प के लिए कोई दस्तावेज नहीं है, इसलिए यह केवल मेरी धारणा है।
फ्रैंकलिन यू

ओह, add_referenceकार्रवाई में एक :foreign_keyविकल्प है जो एक उपयुक्त विदेशी कुंजी बाधा जोड़ता है । मुझे लगता है कि यह विकल्प तालिका बनाते समय भी ऐसा ही करेगा।
फ्रेंकलिन यू

आप अपने रूबी डीबी को कार्यक्षेत्र में कैसे निर्यात करते हैं? क्या आप शायद इसका जवाब यहां दे सकते हैं: stackoverflow.com/questions/42982921/…
क्राव्ला

होने पर पड़ता है add_foreign_key :microposts, :users रेल के लिए कोई फर्क?
लिनस

17

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

 belongs_to :something

तलाश करना है something_id

references, या belongs_toवास्तव में कुछ quirks के साथ पूर्व लिखने का नया तरीका है।

महत्वपूर्ण यह याद रखना है कि यह आपके लिए विदेशी कुंजी नहीं बनाएगा। ऐसा करने के लिए, आपको इसे या तो स्पष्ट रूप से सेट करने की आवश्यकता है:

t.references :something, foreign_key: true
t.belongs_to :something_else, foreign_key: true

या (बहुवचन पर ध्यान दें):

add_foreign_key :table_name, :somethings
add_foreign_key :table_name, :something_elses`

1
क्या आप बता सकते हैं कि आपके कहने का क्या मतलब है कि संदर्भ आपके लिए विदेशी कुंजी नहीं बनाएंगे। यह user_id का उपयोग करके पहली कमांड से अलग कैसे है: पूर्णांक सीधे?
शैलेश

यह ऐसा नहीं है, जब आप :polymorphicविकल्प का उपयोग कर रहे हैं (जो कि ज्यादातर मामलों के लिए IMHO, एक अच्छा विचार नहीं है) को छोड़कर । यदि आप ActiveRecord में विदेशी कुंजियों का उपयोग करना चाहते हैं, तो विदेशी का उपयोग करें ।
क्रूले

1
@ क्रुएल नाउ add_foreign_keyने इसे ActiveRecord में बनाया है।
फ्रैंकलिन यू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.