Добавить миграцию ссылочного столбца в Rails 4

У пользователя много загрузок. Я хочу добавить столбец в таблицу uploads, которая ссылается на user. Как должна выглядеть миграция?

Вот что у меня есть. Я не уверен, следует ли использовать (1) :user_id, :int или (2) :user, :references. Я даже не уверен, что (2) работает. Просто пытаюсь сделать это "рельсы".

class AddUserToUploads < ActiveRecord::Migration
  def change
    add_column :uploads, :user_id, :integer
  end
end

Релевантный вопрос, за исключением Rails 3. Переходы Rails 3: Добавление столбца ссылки?

Ответ 1

Rails 4.x

Если у вас уже есть users и uploads таблицы, и вы хотите добавить новое отношение между ними.

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

rails g migration AddUserToUploads user:references

Что создаст файл миграции как:

class AddUserToUploads < ActiveRecord::Migration
  def change
    add_reference :uploads, :user, index: true
  end
end

Затем запустите миграцию с помощью rake db:migrate. Эта миграция позаботится о добавлении нового столбца с таблицей user_id to uploads (ссылка на столбец id в таблице users), PLUS также добавит индекс в новый столбец.

ОБНОВЛЕНИЕ [для Rails 4.2]

Rails нельзя доверять, чтобы поддерживать ссылочную целостность; реляционные базы данных приходят сюда на помощь. Это означает, что мы можем добавлять ограничения внешнего ключа на уровне базы данных и обеспечивать, чтобы база данных отклоняла любую операцию, которая нарушает эту установленную ссылочную целостность. Как отметил @infoget, Rails 4.2 поставляется с встроенной поддержкой внешних ключей (ссылочная целостность). Это не требуется, но вы можете захотеть добавить внешний ключ (как это очень полезно) к ссылке, которую мы создали выше.

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

class AddForeignKeyToUploads < ActiveRecord::Migration
  def change
    add_foreign_key :uploads, :users
  end
end

Чтобы создать совершенно новую ссылку с внешним ключом (в Rails 4.2), выполните миграцию, используя следующую команду:

rails g migration AddUserToUploads user:references

который создаст файл миграции как:

class AddUserToUploads < ActiveRecord::Migration
  def change
    add_reference :uploads, :user, index: true
    add_foreign_key :uploads, :users
  end
end

Это добавит новый внешний ключ в столбец user_id таблицы uploads. Ключ ссылается на столбец id в таблице users.

ПРИМЕЧАНИЕ.. Это дополнение к добавлению ссылки, поэтому вам еще нужно создать ссылку сначала, а затем внешний ключ (вы можете создать внешний ключ в та же миграция или отдельный файл миграции). Active Record поддерживает только внешние ключи с одним столбцом, и в настоящее время поддерживаются только адаптеры mysql, mysql2 и PostgreSQL. Не пытайтесь использовать это с другими адаптерами, такими как sqlite3 и т.д. Для справки обратитесь к Rails Guides: Foreign Keys.

Ответ 2

Рельсы 5

Вы можете использовать эту команду для создания переноса:

rails g migration AddUserToUploads user:references

Миграция немного отличается от предыдущей, но все еще работает:

class AddUserToUploads < ActiveRecord::Migration[5.0]
  def change
    add_reference :uploads, :user, foreign_key: true
  end
end

Обратите внимание, что :user, а не :user_id

Ответ 3

если вам нравится другой альтернативный подход с помощью методов up и down, попробуйте следующее:

  def up
    change_table :uploads do |t|
      t.references :user, index: true
    end
  end

  def down
    change_table :uploads do |t|
      t.remove_references :user, index: true
    end
  end

Ответ 4

[Использование Rails 5]

Сгенерировать перенос:

rails generate migration add_user_reference_to_uploads user:references

Это создаст файл миграции:

class AddUserReferenceToUploads < ActiveRecord::Migration[5.1]
  def change
    add_reference :uploads, :user, foreign_key: true
  end
end

Теперь, если вы наблюдаете файл схемы, вы увидите, что в таблице загрузок содержится новое поле. Что-то вроде: t.bigint "user_id" или t.integer "user_id".

Перенос базы данных:

rails db:migrate

Ответ 5

Другим синтаксисом для выполнения того же:

rails g migration AddUserToUpload user:belongs_to

Ответ 6

Просто документировать, если у кого-то есть такая же проблема...

В моей ситуации я использовал поля :uuid, и приведенные выше ответы не работают в моем случае, потому что рельсы 5 создают столбец, используя :bigint вместо :uuid:

add_column :uploads, :user_id, :uuid
add_index :uploads, :user_id
add_foreign_key :uploads, :users