結論
reversible do |direction| direction.up { execute "ALTER TABLE battles ADD PRIMARY KEY (id);" } end
環境
なぜつけるのか
railsのマイグレーションでindexつけたりとか特殊なことをしようとするときはexecute()
を使うこともあると思う。
が、db:migrateは成功するものの、
== 20180611044744 CreateBattles: migrating ==================================== -- create_table(:battles, {:id=>false}) -> 0.1625s -- execute("ALTER TABLE battles ADD PRIMARY KEY (id);") -> 0.2046s == 20180611044744 CreateBattles: migrated (0.3674s) ===========================
db:rollbackで戻ろうとするとActiveRecord::IrreversibleMigrationでコケる。
== 20180611044744 CreateBattles: reverting ==================================== rails aborted! StandardError: An error has occurred, all later migrations canceled: This migration uses execute, which is not automatically reversible. To make the migration reversible you can either: 1. Define #up and #down methods in place of the #change method. 2. Use the #reversible method to define reversible behavior. /db/migrate/20180611044744_create_battles.rb:43:in `change' bin/rails:4:in `<main>' Caused by: ActiveRecord::IrreversibleMigration: This migration uses execute, which is not automatically reversible. To make the migration reversible you can either: 1. Define #up and #down methods in place of the #change method. 2. Use the #reversible method to define reversible behavior. /db/migrate/20180611044744_create_battles.rb:43:in `change' bin/rails:4:in `<main>' Tasks: TOP => db:rollback (See full trace by running task with --trace)
冒頭で書いたように、ちゃんとreversibleブロックの中で実行すると大丈夫 reversibleは可逆の意味
reversible do |direction| direction.up { execute "ALTER TABLE battles ADD PRIMARY KEY (id);" } end
詳しくは以下
Active Record マイグレーション | Rails ガイド 3.9 reversibleを使用する
本来はdownも書くんだけど、今回はprymary keyの追加なので割愛