Has_and_belongs_to_many के लिए रेल तालिका में शामिल हों


122

रिश्ते के script/generate migrationलिए जॉइन टेबल बनाने के लिए मैं कैसे करूँ has_and_belongs_to_many?

आवेदन रेल 2.3.2 पर चलता है, लेकिन मेरे पास भी 3.0.3 स्थापित है।

जवाबों:


228

कहाँ पे:

class Teacher < ActiveRecord::Base
  has_and_belongs_to_many :students
end

तथा

class Student < ActiveRecord::Base
  has_and_belongs_to_many :teachers
end

रेल के लिए 4:

rails generate migration CreateJoinTableStudentTeacher student teacher

रेल के लिए 3:

rails generate migration students_teachers student_id:integer teacher_id:integer

रेल के लिए <3

script/generate migration students_teachers student_id:integer teacher_id:integer

(तालिका का नाम सूचीबद्ध करें दोनों वर्णमाला क्रम में तालिकाओं में शामिल हों)

और उसके बाद केवल 3 और उससे नीचे की रेल के लिए, आपको अपना जनरेट किया हुआ माइग्रेशन संपादित करने की आवश्यकता होती है ताकि कोई आईडी फ़ील्ड न बने:

create_table :students_teachers, :id => false do |t|

16
यह एकमात्र उत्तर है जो वास्तव में प्रश्न का उत्तर देता है।
pingu

8
@pingu: सिवाय इसके कि यह काम नहीं करता है, कम से कम रेल 3.2 में। उत्पन्न माइग्रेशन फ़ाइल रिक्त है।
हॉफमैन

7
रेल्स 4. के लिए काम करता है
फेलिप ज़ावन

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

1
हैलो, मैं के rails generate migration CreateJoinTableTeacherStudent teacher studentबजाय कोशिश कर रहा हूँ rails generate migration CreateJoinTableStudentTeacher student teacher, वही है? S (tudent) को T (प्रत्येक) से पहले की आवश्यकता है?
zx1986

138

एक has_and_belongs_to_manyतालिका को इस प्रारूप से मेल खाना चाहिए। मैं मान रहा हूं कि दो मॉडल has_and_belongs_to_manyडीबी में पहले से शामिल हैं: applesऔर oranges:

create_table :apples_oranges, :id => false do |t|
  t.references :apple, :null => false
  t.references :orange, :null => false
end

# Adding the index can massively speed up join tables. Don't use the
# unique if you allow duplicates.
add_index(:apples_oranges, [:apple_id, :orange_id], :unique => true)

आप का उपयोग करते हैं :unique => trueसूचकांक पर है, तो आप (rails3 में) पास करना चाहिए :uniq => trueकरने के लिए has_and_belongs_to_many

अधिक जानकारी: रेल डॉक्स

2010-12-13 तक मैंने आईडी और टाइमस्टैम्प को हटाने के लिए इसे अपडेट कर दिया है ... मूल रूप से MattDiPasqualeऔर nunopoloniaसही हैं: एक आईडी नहीं होनी चाहिए और टाइमस्टैम्प या रेल नहीं होनी चाहिए has_and_belongs_to_many


6
दरअसल, एक ज्वाइन टेबल में केवल दो संदर्भ कॉलम होने चाहिए और उसमें आईडी या टाइमस्टैम्प कॉलम नहीं होना चाहिए। यहां आपके द्वारा दिए गए लिंक से has_and_belongs_to_many माइग्रेशन का एक बेहतर उदाहरण है । मैं कमांड लाइन से इसे करने का तरीका ढूंढ रहा हूं script/generate migration...
ma11hew28

खैर, यह टाइमस्टैम्प के लिए नहीं है; मैंने इसे अपने उदाहरण में वैकल्पिक चिह्नित किया। मैं आईडी जोड़ने की सलाह दूंगा, हालांकि। ऐसे मामले हैं जहां या तो आईडी या टाइमस्टैम्प उपयोगी हो सकते हैं। लेकिन मैं दृढ़ता से आईडी की सिफारिश करता हूं।
docwhat

ठीक। ऐसा क्या मामला है जहां आईडी उपयोगी होगी?
ma11hew28

एक उदाहरण यह है कि संबंध महत्वपूर्ण है कि क्या कोई दृश्य है। इसका उपयोग रिश्ते को बार-बार देखने के बजाय डेटास को एक्सेस करने में तेजी लाने के लिए किया जा सकता है। यह डेटाबेस के समस्या निवारण को भी आसान बनाता है। खासकर अगर अन्य कॉलम की आईडी वास्तव में अधिक है। आईडी को याद रखना आसान है: आईडी के बजाय 12345: 54321-आईडी: 67890 - लेकिन कहा जा रहा है, यदि तालिका वास्तव में बड़ी हो जाती है, तो आप प्रत्येक रिश्ते के लिए दूसरी आईडी आवंटित नहीं करके अंतरिक्ष को बचाने में सक्षम होना चाह सकते हैं।
docwhat

2
मुझे नहीं लगता कि इसके लिए बहुरंगी सूचकांक सही समाधान है। यह संबंधित सेबों के लिए प्रश्नों के लिए संबंधित संतरे खोजने के लिए काम करेगा, लेकिन दूसरे तरीके से नहीं। दो एकल स्तंभ अनुक्रमणिका दोनों दिशाओं को एक विशेष सेब, नारंगी संयोजन के अस्तित्व की जांच के लिए एक छोटे से नुकसान पर संभवतः कुशलतापूर्वक क्वेरी करने की अनुमति देगा।
जोसेफ लॉर्ड

14

आपको तालिका को उन 2 मॉडलों का नाम देना चाहिए जिन्हें आप वर्णानुक्रम से कनेक्ट करना चाहते हैं और तालिका में दो मॉडल आईडी डालते हैं। फिर मॉडल में संघों को बनाने के लिए प्रत्येक मॉडल को एक-दूसरे से कनेक्ट करें।

यहाँ एक उदाहरण है:

# in migration
def self.up
  create_table 'categories_products', :id => false do |t|
    t.column :category_id, :integer
    t.column :product_id, :integer
  end
end

# models/product.rb
has_and_belongs_to_many :categories

# models/category.rb
has_and_belongs_to_many :products

लेकिन यह बहुत लचीला नहीं है और आपको has_many का उपयोग करने के बारे में सोचना चाहिए: के माध्यम से


6

शीर्ष उत्तर एक समग्र सूचकांक दिखाता है जो मुझे विश्वास नहीं है कि इसका उपयोग संतरे से सेब देखने के लिए किया जाएगा।

create_table :apples_oranges, :id => false do |t|
  t.references :apple, :null => false
  t.references :orange, :null => false
end

# Adding the index can massively speed up join tables.
# This enforces uniqueness and speeds up apple->oranges lookups.
add_index(:apples_oranges, [:apple_id, :orange_id], :unique => true)
# This speeds up orange->apple lookups
add_index(:apples_oranges, :orange_id)

मुझे यह जवाब मिला कि यह 'द डॉक्टर व्हाट' द्वारा उपयोगी और चर्चा के आधार पर निश्चित रूप से ऐसा है।


4

रेल 4 में, आप सरल उपयोग कर सकते हैं

create_join_table: table1s,: table2s

यही हे सब।

सावधानी: आपको अल्फ़ान्यूमेरिक के साथ तालिका 1, टेबल 2 को बंद करना होगा।


यह अच्छा समाधान है। ध्यान दें, ज्वाइन टेबल एक मॉडल के रूप में उपलब्ध नहीं है, लेकिन has_and_belongs_to_many संबंधों के माध्यम से जो दोनों शामिल तालिकाओं पर स्थापित हैं।
टेलरिंग वेब साइट्स

1

मुझे करना पसंद है:

rails g migration CreateJoinedTable model1:references model2:references। इस तरह मुझे एक प्रवास मिलता है जो इस तरह दिखता है:

class CreateJoinedTable < ActiveRecord::Migration
  def change
    create_table :joined_tables do |t|
      t.references :trip, index: true
      t.references :category, index: true
    end
    add_foreign_key :joined_tables, :trips
    add_foreign_key :joined_tables, :categories
  end
end

मुझे इन स्तंभों पर अनुक्रमणिका पसंद है क्योंकि मैं अक्सर इन स्तंभों का उपयोग करके लुकअप करूंगा।


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