Відповіді:
Де:
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 і нижче потрібно відредагувати створену міграцію, щоб не було створено поле id:
create_table :students_teachers, :id => false do |t|
rails generate migration CreateJoinTableTeacherStudent teacher student
замість цього rails generate migration CreateJoinTableStudentTeacher student teacher
, це те саме? Чи потрібен S (тюдент) перед T (ечер)?
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
індексом, то вам слід (у рейках3) перейти :uniq => true
до has_and_belongs_to_many
.
Більше інформації: Rails Docs
ОНОВЛЕНО 2010-12-13 Я оновив його, щоб видалити ідентифікатор та часові позначки ... В основному MattDiPasquale
і nunopolonia
правильно: ідентифікатор не повинен бути і не повинно бути часових позначок або рейки не дозволять has_and_belongs_to_many
працювати.
script/generate migration
...
Ви повинні назвати таблицю іменами двох моделей, які ви хочете з'єднати за алфавітом, і помістити два ідентифікатори моделі в таблицю. Потім з'єднайте кожну модель між собою, створюючи асоціації в моделі.
Ось приклад:
# 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: through
У верхній відповіді показаний складений індекс, який, я не вірю, буде використаний для пошуку яблук з апельсинів.
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 можна просто користуватися
create_join_table: table1s,: table2s
це все.
Застереження: ви повинні мати таблицю forford1, table2 з буквено-цифровими.
Мені подобається робити:
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
не вдасться, якщо розмістити їх у тій же міграції, що і та, що створила таблиці.