Rails has_and_belongs_to_many миграция
У меня две модели restaurant
а также user
что я хочу выполнить отношение has_and_belongs_to_many.
Я уже вошел в файлы модели и добавил has_and_belongs_to_many :restaurants
а также has_and_belongs_to_many :users
Я предполагаю, что на этом этапе я смогу сделать что-то вроде Rails 3:
rails generate migration ....
но все, что я пробовал, похоже, не удается. Я уверен, что это что-то действительно простое, я новичок в рельсах, поэтому я все еще учусь.
4 ответа
Вам нужно добавить отдельную таблицу соединений только с restaurant_id
а также user_id
(без первичного ключа), в алфавитном порядке.
Сначала запустите миграцию, затем отредактируйте созданный файл миграции.
Рельсы 3
rails g migration create_restaurants_users_table
Рельсы 4:
rails g migration create_restaurants_users
Рельсы 5
rails g migration CreateJoinTableRestaurantUser restaurants users
Из документов:
Существует также генератор, который будет генерировать таблицы соединений, если JoinTable является частью имени:
Ваш файл миграции (обратите внимание на :id => false
; это то, что мешает созданию первичного ключа):
Рельсы 3
class CreateRestaurantsUsers < ActiveRecord::Migration
def self.up
create_table :restaurants_users, :id => false do |t|
t.references :restaurant
t.references :user
end
add_index :restaurants_users, [:restaurant_id, :user_id]
add_index :restaurants_users, :user_id
end
def self.down
drop_table :restaurants_users
end
end
Рельсы 4
class CreateRestaurantsUsers < ActiveRecord::Migration
def change
create_table :restaurants_users, id: false do |t|
t.belongs_to :restaurant
t.belongs_to :user
end
end
end
t.belongs_to
автоматически создаст необходимые индексы. def change
автоматически обнаружит миграцию вперед или назад, не нужно поднимать / опускать.
Рельсы 5
create_join_table :restaurants, :users do |t|
t.index [:restaurant_id, :user_id]
end
Примечание. Существует также опция для настраиваемого имени таблицы, которое может быть передано в качестве параметра в create_join_table с именем table_name
, Из документов
По умолчанию имя таблицы объединения происходит от объединения первых двух аргументов, предоставленных для create_join_table, в алфавитном порядке. Чтобы настроить имя таблицы, укажите параметр:table_name:
Ответы здесь довольно устарели. Начиная с Rails 4.0.2, ваши миграции используют create_join_table
,
Чтобы создать миграцию, запустите:
rails g migration CreateJoinTableRestaurantsUsers restaurant user
Это создаст следующее:
class CreateJoinTableRestaurantsUsers < ActiveRecord::Migration
def change
create_join_table :restaurants, :users do |t|
# t.index [:restaurant_id, :user_id]
# t.index [:user_id, :restaurant_id]
end
end
end
Если вы хотите проиндексировать эти столбцы, раскомментируйте соответствующие строки, и все готово!
При создании таблицы объединения обращайте особое внимание на требование, чтобы две таблицы были перечислены в алфавитном порядке в имени / классе миграции. Это может легко укусить вас, если названия вашей модели похожи, например, "abc" и "abb". Если бы вы должны были бежать
rails g migration create_abc_abb_table
Ваши отношения не будут работать, как ожидалось. Вы должны использовать
rails g migration create_abb_abc_table
вместо.
Для отношений HABTM вам необходимо создать таблицу соединений. Существует только таблица соединения, и в этой таблице не должно быть столбца идентификатора. Попробуйте эту миграцию.
def self.up
create_table :restaurants_users, :id => false do |t|
t.integer :restaurant_id
t.integer :user_id
end
end
def self.down
drop_table :restaurants_users
end
Вы должны проверить эти отношения руководства по рельсам