Rails 3の移行:参照列を追加しますか?


162

(例)で新しいRails 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
たとえば、edgeguides.rubyonrails.org / active_record_migrations.htmlのセクション2.1を参照してください。
Bセブン

2
自動生成された名前の代わりに外部キーの列名をどのように指定しますか?
jは

@jwill polymorphic:user:references {polymorphic}を使用できます。
パウロフィダルゴ2015

@PauloFidalgoそれを行う方法について少し説明できますか?リンクのガイドかもしれませんか?(ポリモーフィックについて話す)
Anwar


186

編集:これは古い回答であり、Rails 4.x +には適用しないでください

参照されるクラスに整数IDを使用できる場合は、参照を追加する必要はありません。

単純な整数の代わりに参照を使用する利点は、モデルがbelongs_toで事前定義されていることです。モデルはすでに作成されており、既存のものを移行しても影響を受けないため、目的はある程度失われます。

だから私は代わりにこれをしたいと思います:

rails g migration add_user_id_to_tester user_id:integer

次に、テスターモデルにbelongs_to:userを手動で追加します


9
しかし、それはそれをサポートするデータベースに適切な外部キー制約を作成しませんよね?
abahgat

19
いいえ、プラグインを追加しない限り、afaik Railsはデータベースに外部キー制限を作成しません。
DanneManne 2011年

この投稿を勉強するだけで、結局どのように参照を追加するのですか
El nino '19 / 07/19

13
user:integer:indexでインデックスを追加することを忘れないでください
rickypai

3
回答には日付が付いています。最新のレールについては@Pauloの回答を参照してください。
OneHoopyFrood 2015年

102

その列にもインデックスが必要になる可能性が高いことに注意してください。

class AddUserReferenceToTester < ActiveRecord::Migration
  def change
    add_column :testers, :user_id, :integer
    add_index  :testers, :user_id
  end
end

1
どうして?これはほとんどのbelongs_to関係に当てはまりますか?
ahnbizcad 2014

これは確かにパフォーマンス上の理由であり、belongs_toリレーションの反対側にhas_many / has_oneがある場合に便利です。実行しないことが確実である場合はuser.testers、インデックスを省略できます。
ユージーン

1
rails g migration ...生成されたadd_reference :installs, :device, index: true、インデックスを作成します。
Bセブン

49

上記の2つの前のステップでは、外部キー制約がまだありません。これはうまくいくはずです:

  class AddUserReferenceToTester < ActiveRecord::Migration
      def change
          add_column :testers, :user_id, :integer, references: :users
      end
  end

これが唯一の実際の答えです。ここで最も重要な部分は外部キーです
user2490003 2015

質問は、レール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
メソッドを変更してダウンしますか?代わりにupおよびdownメソッドではありませんか?
MaicolBen、2015年

@MaicolBenはい、そして単にダウンメソッドを省くこともできます。
Hut8 2015年

@MaicolBenメソッドがないと、Rails 3.2を使用してロールバックしたときdownに取得しましActiveRecord::IrreversibleMigrationた。私もに変更する必要がありchangeましたup
Andrew Grimm 2016年

27

実行rails g migration AddUserRefToSponsors user:referencesすると、次の移行が生成されます。

def change
  add_reference :sponsors, :user, index: true
end

これはどのバージョンのRailsですか?
Andrew Grimm 2016年

8

列を追加するときは、その列を整数にし、可能であればレールの規則に従う必要があります。したがって、あなたのケースでは、テスターとユーザーのモデル、テスターとユーザーのテーブルがすでにあると想定しています。

外部キーを追加するには、user_id(規則)という名前の整数列を作成する必要があります。

add_column :tester, :user_id, :integer

次に、belongs_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 2014

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

Rails 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

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