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


310

ユーザーは多くのアップロードを持っています。を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以外の関連する質問。Rails3の移行:参照列を追加しますか?

回答:


706

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_iduploadsテーブルに名前が付けられた新しい列(テーブルの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

これuser_idにより、uploadsテーブルの列に新しい外部キーが追加されます。キーidusersテーブルの列を参照します。

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


8
多くの場合、外部キーも追加するとよいでしょう。add_foreign_key(Rails 4.2)
poerror

18
add_reference:uploads、:user、index:true、foreign_key:true @KirtiThorat
user1801879

32
これで、移行に特別なジェネレーター構文を使用する場合、Rails 4.2は外部キー制約を含めて自動的に正しい移行を作成します。適切な移行でrails g migration AddUserToUploads user:references生成さadd_reference :uploads, :user, index: true, foreign_key: trueれます。
jrhorn424 2015

10
...index: true, foreign_key: true代わりにo lineを使用してくださいadd_foreign_key
ワシントンBotelho

2
foreign_keyとの両方が必要なのはなぜt.referenceですか?+とt.reference本質的に同等ではありませんか?foriegn_keyindex
ジオボーイ2017

188

Rails 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


2
以下のような名前に間隔を置いた授業については、Local::User代わりのUserような何かrails g migration AddLocalUserToUploads user:references
Ka Mok

3
これは自動的に追加されます:index
サラバナバラギラマチャンドラン

4
はい@Zeke、移行を実行し、スキーマをチェックし、それが何か言うべきt.index ["user_id"], name: "index_uploads_on_user_id", using: :btree
Mirror318

1
そうです、移行時に手動でadd_indexを追加すると「インデックスが存在します」というエラーが発生しました:P @ Mirror318
サラバ

2
またbelongs_to :userUploadクラスを追加してupload.user、ユーザーインスタンスを取得するために使用できるようにする必要があります。
ウィット

17

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

9

[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

1
この回答は@ Mirror318の回答と重複しているようです。上記の回答に何か不足があると思われる場合は、コメントしてください。ありがとう。
M.ハビブ


7

誰かが同じ問題を抱えているかどうかを記録するだけです...

私の状況では:uuidフィールドを使用していて、上記の回答は私の場合には機能しません。レール5が:bigint代わりにを使用して列を作成しているため:uuidです。

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

また、何が起こっているのかがさらに明確になります。しかし、うんUUIDは今では標準的なはずです。
ハディーズ

2

移行ファイルを作成する

rails generate migration add_references_to_uploads user:references

デフォルトの外部キー名

これにより、uploadsテーブルに外部キーとしてuser_id列が作成されます。

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

ユーザーモデル:

class User < ApplicationRecord
  has_many :uploads
end

アップロードモデル:

class Upload < ApplicationRecord
  belongs_to :user
end

外部キー名をカスタマイズします。

add_reference :uploads, :author, references: :user, foreign_key: true

これにより、uploadsテーブルにauthor_id列が外部キーとして作成されます。

ユーザーモデル:

class User < ApplicationRecord
  has_many :uploads, foreign_key: 'author_id'
end

アップロードモデル:

class Upload < ApplicationRecord
  belongs_to :user
end
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.