web-dev-qa-db-ja.com

Rails 4に参照列の移行を追加する

ユーザーが多数のアップロードをしています。 uploadsを参照するuserテーブルに列を追加したいです。移行はどのようになりますか?

これが私の持っているものです。 (1):user_id, :intと(2):user, :referencesのどちらを使うべきかよくわかりません。 (2)がうまくいくかどうかさえ私にはわかりません。これを「Rails」の方法でやろうとするだけです。

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

Rails 3以外の関連する質問/ Rails 3の移行:参照列の追加

278
Don P

Rails 4.x

すでに usersuploadsテーブルがあり、 それらの間に新しい関係 を追加したい場合。

必要なのは、次のコマンドを使用して移行を生成することです。

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という名前の新しい列をuploadsテーブルに追加し(idテーブルのusers列を参照)、その新しい列にインデックスも追加します。

UPDATE [For 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

これはuploadsテーブルのuser_id列に新しい外部キーを追加します。キーがidテーブルのusers列を参照しています。

注: これは参照を追加するためのものであり、まだ 最初に参照を作成してから外部キーを作成する 同じ移行で外部キーを作成することもできます)または別の移行ファイル)。 Active Recordは単一列の外部キーのみをサポートし、現在はmysqlmysql2、およびPostgreSQLアダプタのみがサポートされています。 sqlite3などの他のアダプタでこれを試してはいけません。あなたの参考のために Railsガイド:外部キー を参照してください。

639
Kirti Thorat

レール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です。

160
Mirror318

updownメソッドを使った別のアプローチが好きなら、これを試してください:

  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
11
Kiry Meas

[Using 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

スキーマファイルを見ると、uploadsテーブルに新しいフィールドが含まれていることがわかります。 t.bigint "user_id"t.integer "user_id"のようなものです。

データベースを移行します。

Rails db:migrate
8
vantony

同じことをするためのもう1つの構文は、次のとおりです。

Rails g migration AddUserToUpload user:belongs_to
6
Nadeem Yasin

誰かが同じ問題を抱えているかどうかを文書化するために...

私の状況では:uuidフィールドを使用してきましたが、Rails 5は:bigintの代わりに:uuidを使用して列を作成しているので、上記の答えはうまくいきません。

add_column :uploads, :user_id, :uuid
add_index :uploads, :user_id
add_foreign_key :uploads, :users
3
Bruno Casali