web-dev-qa-db-ja.com

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

新しいRails 3移行を作成した場合(たとえば)

Rails g migration tester title:tester user:references

、すべてが正常に動作します...ただし、次の行に沿って何かで列を追加した場合:

Rails g migration add_user_to_tester user:references

参照フィールドは認識されません。つまり、質問は次のとおりです。コマンドラインからRails移行に参照列を追加するにはどうすればよいですか。

162
PlankTon

Rails 4.xを使用している場合、次のような参照を使用して移行を生成できるようになりました。

Rails generate migration AddUserRefToProducts user:references

レールガイド で見ることができるように

204
Paulo Fidalgo

EDIT:これは時代遅れの回答であり、Rails 4.x +には適用すべきではありません

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

プレーン整数の代わりに参照を使用する利点は、belongs_toでモデルが事前定義され、既存の何かを移行するときにモデルがすでに作成されており、影響を受けないため、目的が失われるということです。

だから私は代わりにこれが好きです:

Rails g migration add_user_id_to_tester user_id:integer

そして、手動でTesterモデルにbelongs_to:userを追加します

186
DanneManne

ほとんどの場合、その列にもインデックスが必要になることに注意してください。

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

上記の2つの手順では、外部キー制約がまだありません。これは動作するはずです:

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

変更移行で参照を使用できるcan。これは有効な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

c.f .: http://apidock.com/Rails/ActiveRecord/ConnectionAdapters/SchemaStatements/change_table

35
gl03

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

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

それはトリックを行います:

Rails g migration add_user_to_tester user_id:integer:index
8
masterweily

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

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

add_column :tester, :user_id, :integer

次に、belongs_toをテスターモデルに追加します。

class Tester < ActiveRecord::Base
  belongs_to :user
end

また、外部キーのインデックスを追加することもできます(これは、参照によって既に行われていることです)。

add_index :tester, :user_id
8
Zamith

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列と、デフォルト値がPhotoの文字列attachment_type列を追加します。

http://guides.rubyonrails.org/v3.2.21/migrations.html#creating-a-standalone-migration

3
shilovk

次の方法で、コマンドラインからモデルに参照を追加できます。

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
Neha