Rails移行で既存のテーブルに列を追加する


340

:email列を必要とするユーザーモデルがあります(最初の足場でその列を追加するのを忘れていました)。

移行ファイルを開いて、追加t.string :email、実行rake db:migrate、取得しましたNoMethodError。次に、行を追加しました

add_column :users, :email, :string

もう一度rake db:migrateもう一度NoMethodError。ここにステップがないのですか?

編集:ここに移行ファイルがあります。

class CreateUsers < ActiveRecord::Migration  
  def self.up  
    add_column :users, :email, :string  
    create_table :users do |t|  
      t.string :username  
      t.string :email  
      t.string :crypted_password  
      t.string :password_salt  
      t.string :persistence_token  

      t.timestamps  
    end  
  end  

  def self.down  
    drop_table :users  
  end  
end

回答:


573

(それを編集する前に)元のマイグレーションを既に実行している場合は、新しいマイグレーションを生成する必要があります(rails generate migration add_email_to_users email:stringトリックを実行します)。次の行を含む移行ファイルが作成されます。 add_column :users, email, string 次にa rake db:migrateを実行すると、新しい移行が実行され、新しい列が作成されます。

元の移行をまだ実行していない場合は、実行しようとしているように、それを編集できます。移行コードはほぼ完璧です。add_column行を完全に削除するだけです(そのコードは、テーブルが作成される前にテーブルに列を追加しようとし、テーブル作成コードはすでに更新されて、t.string :emailいずれにせよ)。


6
明確にするために、複数形を使用しますか?だから、だadd_email_to_usersとしませんかadd_email_to_user
Purplejacket 2013

9
正しい。Railsのテーブル名は常に複数です(DBの規則に合わせるため)。
camdez 2014年

2
rails db:migrate最後のステップにも使用できます。
Dylan Vander Berg

テーブルの特定の位置に新しい列を作成することは可能ですか?たとえば、既存の「メール」フィールドの直後に新しいフィールド「ステータス」を作成する場合はどうすればよいですか。
neeraj 2018

2
@neerajあなたはおそらく今までに答えを持っていますが、他の求職者はそうです、たとえばt.string :column_x, limit: 10, after: :column_y(少なくともRails 4の場合)
244an

123

Railsコンソールでこのコマンドを使用する

rails generate migration add_fieldname_to_tablename fieldname:string

そして

rake db:migrate

この移行を実行するには


57

時々rails generate migration add_email_to_users email:stringこのような移行を生成します

class AddEmailToUsers < ActiveRecord::Migration[5.0]
  def change
  end
end

その場合、手動でadd_columnto する必要がありますchange

class AddEmailToUsers < ActiveRecord::Migration[5.0]
  def change
    add_column :users, :email, :string
  end
end

そして、実行します rake db:migrate


1)rails generate migration add_email_to_users email:stringこれbundle exec rails cはターミナルの後またはターミナル内で実行する必要がありますか?2)クエリを実行すると、生成されたファイルはどこに配置されますか?
sofs1

28

あなたもすることができます

rake db:rollback

テーブルにデータを追加していない場合は、メール列を追加して移行ファイルを編集し、

rake db:migrate

これは、システムにレール3.1以降がインストールされている場合に機能します。

それを行うはるかに簡単な方法は、移行ファイルの変更をそのままにすることです。使用する

$rake db:migrate:redo

これにより、最後の移行がロールバックされ、再度移行されます。


21

列を追加するには、次の手順を実行する必要があります。

  1. rails generate migration add_fieldname_to_tablename fieldname:string

    オルタナティブ

    rails generate migration addFieldnameToTablename

    移行が生成されたら、移行を編集して、その列に追加するすべての属性を定義します。

    :Railsのテーブル名は常に複数です(DBの規則に合わせるため)。前述のステップの1つを使用した例

    rails generate migration addEmailToUsers

  2. rake db:migrate

または

  1. からスキーマを変更できdb/schema.rbます。SQLクエリに必要な列を追加します。
  2. 次のコマンドを実行します。 rake db:schema:load

    警告/注意

    実行rake db:schema:loadすると、テーブル内のすべてのデータが自動的にワイプされることに注意してください。


私はこれを行いましたが、「足場」をやり直して新しい列を追加しませんでした。どうすれば「自動的に」それを行うことができますか?
John Wooten

@John Wooten、足場を削除してもう一度やり直してください。対応するマイグレーションも削除します。
Afolabi Olaoluwa Akinwumi 16

メモを追加するには、移行を変更せずにスキーマを変更すると、アプリを管理している他の開発者に問題が発生する可能性があります。
BKSpurgeon

3

これを行ったら、元の移行をいじるのではなく、上のセクションに列を追加し、下のセクションに列をドロップするだけで新しいマイグレーションを作成します。

元のバージョンを変更して、その間で移行する場合は再実行できますが、この場合、正しく機能しない移行が行われたと思います。

現在投稿されているとおり、列を追加してからテーブルを作成しています。

順序を変えるとうまくいくかもしれません。または、既存の移行を変更する場合は、個別の追加列を実行する代わりに、それを作成テーブルに追加するだけです。


1

force: trueテーブルが既に存在する場合は、を使用してテーブル内のテーブル列を強制することもできます。

ActiveRecord::Schema.define(version: 20080906171750) do
  create_table "authors", force: true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
  end
end

1

新しい列を追加するために、移行で特別なchange_tableメソッドを使用することもできます。

change_table(:users) do |t|
  t.column :email, :string
end

0

最後の移行をロールバックできます

rake db:rollback STEP=1

またはこの特定の移行をロールバックします

rake db:migrate:down VERSION=<YYYYMMDDHHMMSS>

ファイルを編集してから、rake db:mirgateもう一度実行してください。



0

次のように、前列または後列を使用して、特定の位置に列を追加することもできます。

rails generate migration add_dob_to_customer dob:date

移行ファイルは、後を除いて次のコードを生成します::email。after::emailまたはbefore::emailを追加する必要があります

class AddDobToCustomer < ActiveRecord::Migration[5.2]
  def change
    add_column :customers, :dob, :date, after: :email
  end
end
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.