Генерировать модель с использованием пользователя: ссылки vs user_id: integer

Я запутался в том, как создать модель, принадлежащую другой модели. Моя книга использует этот синтаксис для связи Micropost с пользователем:

rails generate model Micropost user_id:integer

но http://guides.rubyonrails.org/ говорит, чтобы сделать это следующим образом:

rails generate model Micropost user:references

Миграции, генерируемые этими 2, различны. Кроме того, для первого, как рельсы знают, что user_id является внешним ключом, ссылающимся на user? Спасибо!

Ответ 1

Оба будут генерировать те же столбцы при выполнении миграции. В консоли rails вы можете видеть, что это так:

:001 > Micropost
=> Micropost(id: integer, user_id: integer, created_at: datetime, updated_at: datetime)

Вторая команда добавляет отношения belongs_to :user в вашу модель Micropost, тогда как первая не делает этого. Когда это отношение указано, ActiveRecord будет считать, что внешний ключ хранится в столбце user_id, и он будет использовать модель с именем User для создания экземпляра конкретного пользователя.

Вторая команда также добавляет индекс в новый столбец user_id.

Ответ 2

как рельсы знают, что user_id является внешним ключом, ссылающимся на user?

Rails сам не знает, что user_id является внешним ключом, ссылающимся на user. В первой команде rails generate model Micropost user_id:integer она добавляет только столбец user_id, однако рельсы не знают использования col. Вам нужно вручную поместить строку в модель Micropost

class Micropost < ActiveRecord::Base
  belongs_to :user
end

class User < ActiveRecord::Base
  has_many :microposts
end

ключевые слова belongs_to и has_many определяют взаимосвязь между этими моделями и объявляют user_id как внешний ключ к модели user.

Более поздняя команда rails generate model Micropost user:references добавляет строку belongs_to :user в модель Micropost и настоящим объявляет как внешний ключ.

FYI
Объявление внешних ключей с использованием прежнего метода позволяет Rails знать об отношениях, которые имеют модели/таблицы. База данных неизвестна об отношениях. Поэтому, когда вы создаете диаграммы EER с использованием программного обеспечения, такого как MySql Workbench, вы обнаружите, что между моделями нет нити отношений. Как на следующем рисунке введите описание изображения здесь

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

def change
    create_table :microposts do |t|
      t.references :user, index: true

      t.timestamps null: false
    end
    add_foreign_key :microposts, :users

Теперь внешний ключ устанавливается на уровне базы данных. и вы можете генерировать правильные диаграммы EER. введите описание изображения здесь

Ответ 3

Для первого - соглашение по конфигурации. Rails по умолчанию, когда вы ссылаетесь на другую таблицу с помощью

 belongs_to :something

- искать something_id.

references, или belongs_to - фактически новый способ написания первого с небольшим количеством причуд.

Важно помнить, что он не будет создавать внешние ключи для вас. Чтобы сделать это, вам нужно настроить его явно, используя либо:

t.references :something, foreign_key: true
t.belongs_to :something_else, foreign_key: true

или (обратите внимание на множественное число):

add_foreign_key :table_name, :somethings
add_foreign_key :table_name, :something_elses`