Rails имеет и принадлежит многим миграции


у меня есть две модели restaurant и user что я хочу выполнить отношение has_and_belongs_to_many.

Я уже вошел в файлы модели и добавил has_and_belongs_to_many :restaurants и has_and_belongs_to_many :users

Я предполагаю, что в этот момент я должен быть в состоянии сделать что-то вроде Rails 3:

rails generate migration ....

но все, что я пробовал, кажется, не получится. Я уверен, что это что-то действительно простое, я новичок в rails, поэтому я все еще учусь.

4 100

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

С docs:

существует также генератор, который будет производить объединение таблиц, если 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. Из docs

по умолчанию имя соединяемой таблицы происходит от объединения первые два аргумента, предоставленные 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

вы должны проверить это отношение рельсы руководство учебники