Odpowiedzi:
Gdzie:
class Teacher < ActiveRecord::Base
has_and_belongs_to_many :students
end
i
class Student < ActiveRecord::Base
has_and_belongs_to_many :teachers
end
dla szyn 4:
rails generate migration CreateJoinTableStudentTeacher student teacher
dla szyn 3:
rails generate migration students_teachers student_id:integer teacher_id:integer
dla szyn <3
script/generate migration students_teachers student_id:integer teacher_id:integer
(zwróć uwagę, że nazwa tabeli zawiera obie tabele łączenia w kolejności alfabetycznej)
a następnie tylko dla szyn 3 i niższych, musisz edytować wygenerowaną migrację, aby pole identyfikatora nie zostało utworzone:
create_table :students_teachers, :id => false do |t|
rails generate migration CreateJoinTableTeacherStudent teacher student
zamiast rails generate migration CreateJoinTableStudentTeacher student teacher
, czy to to samo? Czy S (tudent) musi przed T (eacher)?
has_and_belongs_to_many
Stół musi pasować ten format. Zakładam, że dwa modele, które mają zostać połączone, has_and_belongs_to_many
są już w bazie danych: apples
i 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)
Jeśli używasz :unique => true
indeksu, powinieneś (w rails3) przejść :uniq => true
do has_and_belongs_to_many
.
Więcej informacji: Rails Docs
ZAKTUALIZOWANO 2010-12-13 Zaktualizowałem go, aby usunąć identyfikator i znaczniki czasu ... Zasadniczo MattDiPasquale
i nunopolonia
są one poprawne: nie może być identyfikatora i nie może być znaczników czasu ani szyn, które nie pozwolą has_and_belongs_to_many
działać.
script/generate migration
...
Powinieneś nazwać tabelę nazwami 2 modeli, które chcesz połączyć w kolejności alfabetycznej i umieścić dwa identyfikatory modeli w tabeli. Następnie połącz każdy model ze sobą, tworząc w modelu skojarzenia.
Oto przykład:
# 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
Ale to nie jest zbyt elastyczne i powinieneś pomyśleć o użyciu has_many: through
Górna odpowiedź pokazuje złożony indeks, który, jak sądzę, nie będzie używany do wyszukiwania jabłek z pomarańczy.
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)
Uznałem, że odpowiedź, na podstawie której jest to oparte na „Doktorze What”, jest użyteczna i dyskusja z pewnością również.
W szynach 4 można łatwo używać
create_join_table: table1s,: table2s
to wszystko.
Uwaga: tabelę1, tabelę2 należy wyłączyć alfanumerycznie.
Lubię robić:
rails g migration CreateJoinedTable model1:references model2:references
. W ten sposób otrzymuję migrację, która wygląda następująco:
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
Lubię mieć indeksy w tych kolumnach, ponieważ często będę wyszukiwać za pomocą tych kolumn.
add_foreign_key
zakończy się niepowodzeniem, jeśli zostanie umieszczony w tej samej migracji, co ta, która utworzyła tabele.