Rails миграция для таблицы соединений has_and_belongs_to_many - PullRequest
121 голосов
/ 07 декабря 2010

Как мне сделать script/generate migration для создания таблицы соединения для отношения has_and_belongs_to_many?

Приложение работает на Rails 2.3.2, но у меня также установлен Rails 3.0.3.

Ответы [ 6 ]

225 голосов
/ 07 мая 2011

Где:

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 </strong>

script/generate migration students_teachers student_id:integer teacher_id:integer

(обратите внимание, что в названии таблицы перечислены обе таблицы объединения в алфавитном порядке)

, а затем только для рельсов 3 и ниже, вам нужно отредактировать созданную миграцию, чтобы поле id не создавалось:

create_table :students_teachers, :id => false do |t|
138 голосов
/ 07 декабря 2010
Таблица

A 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.

Дополнительная информация: Документация по Rails

ОБНОВЛЕНО 2010-12-13 Iобновил его для удаления идентификатора и временных меток ... В основном MattDiPasquale и nunopolonia верны: не должно быть идентификатора и не должно быть временных меток, или рельсы не позволят has_and_belongs_to_many работать.

14 голосов
/ 07 декабря 2010

Вам следует присвоить таблице имена двух моделей, которые вы хотите подключить, в алфавитном порядке и поместить два идентификатора модели в таблицу.Затем соедините каждую модель друг с другом, создавая ассоциации в модели.

Вот пример:

# 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

6 голосов
/ 28 февраля 2014

В верхнем ответе показан составной индекс, который, я не думаю, будет использоваться для поиска яблок из апельсинов.

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 голосов
/ 16 октября 2014

В рельсах 4 вы можете просто использовать

create_join_table: table1s,: table2s

это все.

Осторожно: вы должны использовать таблицы 1, 2 с буквенно-цифровыми символами.

1 голос
/ 04 марта 2015

Мне нравится делать:

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

Мне нравится иметь индекс для этих столбцов, потому что я часто буду выполнять поиск с использованием этих столбцов.

...