remove_columnのrollbackでActiveRecord::IrreversibleMigrationエラーが発生したときの対応方法

背景

Create tableのマイグレーションで追加したカラムが必要なくなったので、remove_columnのマイグレーションを行いました。

マイグレーションファイルはこちら

1
2
3
4
5
class RemoveTitleFromExamples < ActiveRecord::Migration
def change
remove_column :examples, :title
end
end

マイグレーションは成功してtitleというカラムはなくなりました。

ところがやっぱりtitleというカラムが必要ということで、上記で実施したマイグレーションを元に戻そうとしました。すると以下のようにエラーが発生してしまいました…

1
2
3
4
5
6
7
8
9
10
11
$ ./bin/rails db:rollback
StandardError: An error has occurred, all later migrations canceled:

remove_column is only reversible if given a type.

(中略)

Caused by:
ActiveRecord::IrreversibleMigration:

remove_column is only reversible if given a type.

エラーメッセージを見れば対応方法は分かりそうですね

対応方法

エラーメッセージにある

1
remove_column is only reversible if given a type.

が答えですね。型を与えてあげればrollbackが可能ということです。ですので、先ほどのマイグレーションファイルを以下のように変更します。

1
2
3
4
5
class RemoveTitleFromExamples < ActiveRecord::Migration
def change
remove_column :examples, :title, :string
end
end

マイグレーションを実行してみましょう。

1
2
3
4
5
$ ./bin/rails db:rollback
== 20210523211330 RemoveTitleFromExamples: reverting - ===========
-- add_column(:examples, :title, :string)
-> 0.0812s
== 20210523211330 RemoveTitleFromExamples: reverted (0.0845s) - ==

無事追加されました!

ですが、元の位置には追加されておらず、最後に追加されてしまいます…
afterオプションが効くかどうか試してみます。

一旦マイグレーションします。

1
2
3
4
5
$ ./bin/rails db:migrate
== 20210523211330 RemoveTitleFromExamples: migrating - ===========
-- remove_column(:examples, :title, :string)
-> 0.0398s
== 20210523211330 RemoveTitleFromExamples: migrated (0.0399s) - ==

マイグレーションファイルを書き換えます

1
2
3
4
5
class RemoveTitleFromExamples < ActiveRecord::Migration
def change
remove_column :examples, :title, :string, after: :id
end
end

rollbackします

1
2
3
4
5
$ ./bin/rails db:rollback
== 20210523211330 RemoveTitleFromExamples: reverting - ===========
-- add_column(:examples, :title, :string, {:after=>:id})
-> 0.0489s
== 20210523211330 RemoveTitleFromExamples: reverted (0.0522s) - ==

テーブルを確認すると、ちゃんと指定したカラムの後に追加されています!

最後に、カラム削除用に作成したマイグレーションのファイルを削除して完了です。