Rails 3 миграций: добавление ссылочного столбца?

162

Если я создаю новый рельс 3 миграции с (например)

rails g migration tester title:tester user:references

все работает нормально ... однако, если я добавлю столбец с чем-то вроде:

rails g migration add_user_to_tester user:references

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

планктон
источник

Ответы:

205

Если вы используете Rails 4.x , теперь вы можете генерировать миграции со ссылками, например так:

rails generate migration AddUserRefToProducts user:references

как вы можете видеть на направляющих рельсов

Пауло Фидальго
источник
1
Смотрите, например, раздел 2.1 на сайте edgeguides.rubyonrails.org/active_record_migrations.html .
B Семь
2
как указать имя столбца для внешнего ключа вместо автоматически сгенерированного имени?
J будет
@jwill вы можете использовать полиморфный: пользователь: ссылки {полиморфный}.
Пауло Фидальго,
@PauloFidalgo Можете ли вы объяснить, как это сделать? может быть какой-то путеводитель по ссылкам? (говорит о полиморфном)
Анвар
@Anwar: вот документы api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/…
Пауло Фидальго
186

РЕДАКТИРОВАТЬ : Это устаревший ответ и не должны применяться для Rails 4.x +

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

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

Так что я бы сделал так вместо этого:

rails g migration add_user_id_to_tester user_id:integer

А затем вручную добавьте принадлежащего пользователя в модель тестера.

DanneManne
источник
9
Но это не создаст соответствующие ограничения внешнего ключа для баз данных, которые его поддерживают, верно?
Абахгат
19
Нет, afaik Rails никогда не создает ограничения внешних ключей в базе данных, если вы не добавите плагины, чтобы сделать это за вас.
DanneManne
просто изучаю этот пост, пожалуйста, как мне добавить ссылку в конце концов
Эль Ниньо
13
не забудьте добавить индекс с пользователем: integer: index
rickypai
3
Ответ датирован, см. Ответ @ Paulo для современных рельсов.
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 с другой стороны этого отношения own_to. Если вы абсолютно уверены, что не пройдете, 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

gl03
источник
1
изменить и вниз методы? разве нет методов вверх и вниз?
MaicolBen
@MaicolBen да, и вы также можете просто отключить метод down.
Хата8
@MaicolBen Без downметода я получил ActiveRecord::IrreversibleMigrationпри откате с помощью Rails 3.2. Я также должен был измениться changeна up.
Эндрю Гримм
27

Запуск rails g migration AddUserRefToSponsors user:referencesсоздаст следующую миграцию:

def change
  add_reference :sponsors, :user, index: true
end
Wirwing
источник
Для какой версии Rails это?
Эндрю Гримм
8

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

Чтобы добавить внешний ключ, вам нужно создать целочисленный столбец с именем user_id (соглашение):

add_column :tester, :user_id, :integer

Затем добавьте own_to к модели тестера:

class Tester < ActiveRecord::Base
  belongs_to :user
end

И вы также можете добавить индекс для внешнего ключа (это то, что ссылки уже сделали для вас):

add_index :tester, :user_id
Zamith
источник
8

Это сделает свое дело:

rails g migration add_user_to_tester user_id:integer:index
masterweily
источник
Мне нравится, что это также добавляет индекс, который вы, скорее всего, захотите.
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

Для Rails 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

shilovk
источник