сгенерировать модель, используя user: reference против user_id: integer - PullRequest
165 голосов
/ 22 октября 2011

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

rails generate model Micropost user_id:integer

но http://guides.rubyonrails.org/ говорит сделать это так:

rails generate model Micropost user:references

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

Ответы [ 3 ]

182 голосов
/ 22 октября 2011

Оба будут генерировать одинаковые столбцы при запуске миграции.В консоли 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.

42 голосов
/ 16 августа 2015

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

Сам Rails не знает, что user_id является внешним ключом, ссылающимся на user.В первой команде rails generate model Micropost user_id:integer он добавляет только столбец user_id, однако rails не знает, как использовать 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, вы обнаруживаете, что между моделями не нарисованы потоки взаимосвязей.Как показано на следующем рисунке enter image description here

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

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

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

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

15 голосов
/ 22 октября 2011

Для первого, соглашение по конфигурации.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`
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...