Міграція рейків 3: Додавання стовпця-опорного стовпчика?


162

Якщо я створять нову міграцію рейки 3 (наприклад)

rails g migration tester title:tester user:references

, все працює добре ... однак якщо додати стовпчик із чимось у рядках:

rails g migration add_user_to_tester user:references

опорне поле не розпізнається. Коротше кажучи, питання: як я можу додати референтний стовпчик до міграції рейок з командного рядка?

Відповіді:


205

Якщо ви використовуєте Rails 4.x, тепер ви можете генерувати міграції з посиланнями, наприклад:

rails generate migration AddUserRefToProducts user:references

як ви бачите на напрямних напрямних


1
Дивіться, наприклад, розділ 2.1 від edgeguides.rubyonrails.org/active_record_migrations.html, наприклад.
B Сім

2
як вказати ім'я стовпця для іноземного ключа замість автоматично створеного імені?
j

@jwill ви можете використовувати polymorphic: user: reference {polymorphic}.
Пауло Фідальго

@PauloFidalgo Ви можете трохи пояснити, як це зробити? може бути якийсь путівник посилань? (йдеться про поліморфні)
Анвар


186

EDIT : Ця відповідь застаріла, і її не слід застосовувати Rails 4.x +

Вам не потрібно додавати посилання, коли ви можете використовувати цілий ідентифікатор до вашого посилається класу.

Я б сказав, що перевага використання посилань замість простого цілого числа полягає в тому, що модель буде заздалегідь визначена last_to, а оскільки модель вже створена і на неї не впливатиме, коли ви переміщаєте щось існуюче, ціль втрачається.

Тож я хотів би зробити це так:

rails g migration add_user_id_to_tester user_id:integer

А потім вручну додайте last_to: user у модель Tester


9
Але це не створить відповідних зовнішніх ключових обмежень для баз даних, які його підтримують, правда?
абахгат

19
Ні, afaik Rails ніколи не створює обмежень із зовнішніми ключами в базі даних, якщо ви не додасте плагіни, щоб зробити це за вас.
DanneManne

просто вивчаючи цю публікацію, будь ласка, як я можу додати посилання зрештою
El nino

13
не забудьте додати індекс з користувачем: integer: index
rickypai

3
Відповідь датується, дивіться відповідь @ Пауло про сучасні рейки.
OneHoopyFrood

102

Зверніть увагу, що вам, швидше за все, знадобиться і індекс у цьому стовпці.

class AddUserReferenceToTester < ActiveRecord::Migration
  def change
    add_column :testers, :user_id, :integer
    add_index  :testers, :user_id
  end
end

1
Чому? Чи правда це для більшості відносин, які належать до них?
ahnbizcad

Це дійсно з міркувань продуктивності і стане в нагоді, якщо у вас є співвідношення has_many / has_one з іншого боку цього відношення. Якщо ви абсолютно впевнені, що не проходите, user.testersможете пропустити індекс.
Євген

1
rails g migration ...Генеруватися , add_reference :installs, :device, index: trueякий також створює індекс.
B Сім

49

З двома попередніми кроками, зазначеними вище, ви все ще не вистачаєте обмеження на зовнішній ключ. Це має працювати:

  class AddUserReferenceToTester < ActiveRecord::Migration
      def change
          add_column :testers, :user_id, :integer, references: :users
      end
  end

Це єдина фактична відповідь тут. Зовнішній ключ тут є найважливішою частиною
user2490003

це слід позначити як правильну відповідь, оскільки питання задають рейки 3
Карлос Роке

35

Ви можете використовувати посилання для міграції змін. Це дійсний код Rails 3.2.13:

class AddUserToTester < ActiveRecord::Migration
  def change
    change_table :testers do |t|
      t.references :user, index: true 
    end
  end
  def down
    change_table :testers do |t|
      t.remove :user_id
    end
  end
end

cf: http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/change_table


1
змінити та зменшити методи? чи не замість цього способів?
MaicolBen

@MaicolBen так, і ви також можете просто відмовитися від методу вниз.
Хата8

@MaicolBen Без downметоду я отримав, ActiveRecord::IrreversibleMigrationколи відкотився за допомогою Rails 3.2. Я також мав зміни changeв up.
Ендрю Грімм


8

Додаючи стовпчик, потрібно зробити цей стовпець цілим числом і, якщо можливо, дотримуватися конвенцій рейків. Тому для вашого випадку я припускаю, що у вас вже є моделі Tester і User, а також тестери та користувальницькі таблиці.

Щоб додати іноземний ключ, вам потрібно створити цілий стовпець з іменем user_id (convention):

add_column :tester, :user_id, :integer

Потім додайте last_to до моделі тестера:

class Tester < ActiveRecord::Base
  belongs_to :user
end

І ви також можете додати індекс для зовнішнього ключа (це те, що посилання вже робить для вас):

add_index :tester, :user_id

8

Це зробить трюк:

rails g migration add_user_to_tester user_id:integer:index

Мені подобається, що це також додає індекс, який ви, швидше за все, захочете.
bheeshmar

3

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

rails g migration add_column_to_tester user_id:integer

Це створить файл міграції на зразок:

class AddColumnToTesters < ActiveRecord::Migration
  def change
    add_column :testers, :user_id, :integer
  end
end

Це добре працює щоразу, коли я його використовую ..


3

Для рейок 4

Генератор приймає тип стовпця як посилання (також доступний як belongs_to).

Ця міграція створить user_idстовпець і відповідний індекс:

$ rails g migration AddUserRefToProducts user:references 

генерує:

class AddUserRefToProducts < ActiveRecord::Migration
  def change
    add_reference :products, :user, index: true
  end
end

http://guides.rubyonrails.org/active_record_migrations.html#creating-a-standalone-migration

Для рейок 3

Помічником називають посилання (також доступні як belongs_to ).

Ця міграція створить category_idстовпчик відповідного типу. Зауважте, що ви вводите ім'я моделі, а не ім'я стовпця. Active Record додає _idвам.

change_table :products do |t|
  t.references :category
end

Якщо у вас є поліморфні belongs_toасоціації, тоді посилання додадуть обидва стовпчики, необхідні:

change_table :products do |t|
  t.references :attachment, :polymorphic => {:default => 'Photo'}
end

Додасть стовпець attachment_id та attachment_typeстовпчик рядка зі значенням за замовчуваннямPhoto .

http://guides.rubyonrails.org/v3.2.21/migrations.html#creating-a-standalone-migration

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