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 Можете ли вы объяснить, как это сделать? может быть какой-то путеводитель по ссылкам? (говорит о полиморфном)
Анвар


186

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

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

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

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

rails g migration add_user_id_to_tester user_id:integer

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


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


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

Для какой версии 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

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.