Railsでロールバックしてマイグレーションを修正する

FBCRailsを使ったユーザーフォローのプラクティスを進めています。 間違ったマイグレーションロールバックして修正する必要性が出たのでやり方を調べました。

結論

下記手順でDBをロールバックできる。

  1. マイグレーションのバージョン確認
  2. rollback する
  3. マイグレーションファイルを修正
  4. migrate する

実際の手順

上記手順を元にマイグレーションロールバックしてDBの構造を修正する手順です。

1. マイグレーションのバージョン確認

修正前の状態を確認します。

$ rails db:version
Running via Spring preloader in process 65752
Current version: 20221110192153 # ←修正したいマイグレーション

$ rails db:migrate:status
Running via Spring preloader in process 65819

database: db/development.sqlite3

 Status   Migration ID    Migration Name
--------------------------------------------------
   ...
   up     20221110192153  Create friendships # ←修正したいマイグレーション

2. rollbackする

1つ前のマイグレーションrollback します。

$ rails db:rollback
Running via Spring preloader in process 65920
== 20221110192153 CreateFriendships: reverting ================================
# ロールバックの詳細が表示される
== 20221110192153 CreateFriendships: reverted (0.0049s) =======================

rollback したマイグレーションの状態を再度確認します。

$ rails db:version
Running via Spring preloader in process 66000
Current version: 20210531231050 # 1つ前のマイグレーションになっている

$ rails db:migrate:status
Running via Spring preloader in process 66067

database: db/development.sqlite3

 Status   Migration ID    Migration Name
--------------------------------------------------
   ...
   up     20210531231050  Remove omniauth columns from users # 1つ前のマイグレーション
  down    20221110192153  Create friendships # downになっているので正常にロールバックできている

ちなみに1つ以上前のマイグレーションrollback する場合は次のようにバージョンを指定できます。

# 1つ前のバージョンに戻す
$ rails db:rollback

# 任意のバージョンに戻す(number+1 のバージョンまで戻す)
$ rails db:rollback STEP=number

【Rails】$rails db:rollbackしたい時の間違えない手順 - Qiita

3. マイグレーションファイルを修正

下記の方法でマイグレーションファイルを修正します。

今回は作成済みのマイグレーションファイルを修正しました。

4. 再migrateする

修正したマイグレーションファイルを元に再migrate します。

$ rails db:migrate
Running via Spring preloader in process 67368
== 20221110192153 CreateFriendships: migrating ================================
# 新たなマイグレーションの詳細が表示されます
== 20221110192153 CreateFriendships: migrated (0.0026s) =======================

migrate した状態を確認します。 今回は作成済みのマイグレーションファイルを修正してmigrate したのでバージョンは変更されていません。

$ rails db:version
Running via Spring preloader in process 67451
Current version: 20221110192153 # 再migrateしたバージョン、今回はバージョン自体に変更なし

$ rails db:migrate:status
Running via Spring preloader in process 67520

database: db/development.sqlite3

 Status   Migration ID    Migration Name
--------------------------------------------------
   ...
   up     20210531231050  Remove omniauth columns from users # 1つ前のバージョン
   up     20221110192153  Create friendships # 再migrateしたバージョン、upになっていればok

rails db:migrate:statusStatus が全てup になっていれば正しくmigrate できています。

上記手順でRailsロールバックしてマイグレーションを修正することができました。

注意点

Railsロールバックを行う際には次のことに注意した方が良さそうです。

# rollback したままだと発生するエラー
ActiveRecord::PendingMigrationError - Migrations are pending. To resolve this issue, run:

        bin/rails db:migrate RAILS_ENV=development

まとめ

ロールバックについて復習できて良かった。 ロールバックしないように実装前にちゃんと設計する大事さも再確認できました。

追記

ロールバックする前にmigrationファイルを削除してロールバックできなくなった場合の記事も書きました。

【Rails】migrationファイルを削除してしまってロールバックできない時の対処法 - 時々とおまわり

参照

【Rails】$rails db:rollbackしたい時の間違えない手順 - Qiita

rails db:rollbackって一つずつしか差し戻せないんだよって話 - Qiita