генерувати модель за допомогою користувача: посилання проти user_id: integer


176

Мене бентежить те, як генерувати модель, що належить іншій моделі. Моя книга використовує цей синтаксис для асоціації Micropost з користувачем:

rails generate model Micropost user_id:integer

але http://guides.rubyonrails.org/ каже, що робити це так:

rails generate model Micropost user:references

Міграції, породжені цими двома, різні. Крім того, для перших, як рейки знають, що user_idце зовнішній ключ user? Дякую!

Відповіді:


190

Обидва будуть генерувати однакові стовпці при запуску міграції. На консолі рейки ви бачите, що це так:

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

Друга команда додає belongs_to :userспіввідношення у вашій моделі Micropost, тоді як перша не відповідає. Коли цей взаємозв'язок заданий, ActiveRecord буде припускати, що зовнішній ключ зберігається у user_idстовпці, і він використовуватиме модель, іменовану Userдля ідентифікації конкретного користувача.

Друга команда також додає індекс у новому user_idстовпчику.


1
Чи можливо генерувати модель із посиланнями на дві таблиці
praveenkumar

Зауважте, що він не додає асоціації has_many для іншої моделі (користувача), яку ви також можете додати.
Sv1

45

як рейки знають, що user_idце зовнішній ключ user?

Сам Рейлс не знає, що user_idце зовнішній ключ user. У першій команді rails generate model Micropost user_id:integerвін додає лише стовпчик, user_idпроте рейки не знають використання кола. Потрібно вручну поставити лінію в 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діаграми. введіть тут опис зображення


1
Здається, останній генератор Rails замінив add_foreign_keyдію на опцію foreign_key: trueдо t.referencesрядка, що має на увазі index: true. Так це зараз t.references :user, foreign_key: true. Наразі немає foreign_keyдоступної документації для цієї опції, тому це лише моє припущення.
Франклін Ю

О, у add_referenceдії є :foreign_keyваріант, який додає відповідного обмеження для зовнішнього ключа . Я думаю, що цей варіант зробив би те саме при створенні таблиці.
Франклін Ю

Як ви експортуєте свій рубіновий db на верстат? Чи не могли б Ви відповісти на цей питання тут: stackoverflow.com/questions/42982921 / ...
Krawalla

Чи має add_foreign_key :microposts, :users якесь значення для Rails?
Лінус

17

Для першого - конвенція щодо конфігурації. 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`

1
чи можете ви пояснити, що ви маєте на увазі, кажучи, що посилання не створюватимуть сторонні ключі для вас. Чим вона відрізняється від першої команди, що використовує user_id: integer безпосередньо?
shailesh

Це не так, за винятком випадків, коли ви використовуєте :polymorphicваріант (що IMHO, в більшості випадків, не є хорошою ідеєю). Якщо ви хочете використовувати іноземні ключі в ActiveRecord, використовуйте іноземця .
Круле

1
@Krule Now add_foreign_keyзробив це в ActiveRecord.
Франклін Ю
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.