【Rails】データベースに反映済みのマイグレーションファイルの修正方法



マイグレーションファイルを作成して, `rails db:migrate`し, あとからカラム名のタイポに気づきました

```db/migrate/20240502121245_create_checkouts.rb
class CreateCheckouts < ActiveRecord::Migration[7.0]
  def change
    create_table :checkouts do |t|
      t.string :fisrt_name # first_name としたかった
      
      t.timestamps
    end
  end
end
```

`rails db:migrate`していない場合は, そのままマイグレーションファイルを編集すればよいですが, すでにしている場合はデータベースに反映されているため, ロールバックをする必要があります。
反映されているかは`rails db:migrate:status`で確認できます。`up`になっていれば反映済み, `down`になっていれば未反映です。

今回は以下のように`up`になっていました。

```
$ rails db:migrate:status

database: myapp_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20230206140511  Create tasks
   up     20231230034411  Create items
   up     20231230085325  Create active storage tablesactive storage
   up     20240101065120  Add image name to items
   up     20240117124127  Add detail to items
   up     20240204060936  Remove image name from items
   up     20240310104030  Create carts
   up     20240311124017  Create cart items
   up     20240502121245  Create checkouts
```

このためロールバックをしました。以下のように`down`になりました。

```
$ rails db:rollback
== 20240502121245 CreateCheckouts: reverting ==================================
-- drop_table(:checkouts)
   -> 0.1274s
== 20240502121245 CreateCheckouts: reverted (0.2263s) =========================

$ rails db:migrate:status

database: myapp_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20230206140511  Create tasks
   up     20231230034411  Create items
   up     20231230085325  Create active storage tablesactive storage
   up     20240101065120  Add image name to items
   up     20240117124127  Add detail to items
   up     20240204060936  Remove image name from items
   up     20240310104030  Create carts
   up     20240311124017  Create cart items
  down    20240502121245  Create checkouts
```

これで修正可能です。マイグレーションファイルを以下のように修正しました。
```diff_ruby:db/migrate/20240502121245_create_checkouts.rb
class CreateCheckouts < ActiveRecord::Migration[7.0]
  def change
    create_table :checkouts do |t|
-      t.string :fisrt_name
+      t.string :first_name
      
      t.timestamps
    end
  end
end
```

修正したら`rails db:migrate`をしデータベースに反映されているか確認します。

```
$ rails db:migrate
== 20240502121245 CreateCheckouts: migrating ==================================
-- create_table(:checkouts)
   -> 0.1029s
== 20240502121245 CreateCheckouts: migrated (0.1037s) =========================

$ rails db:migrate:status

database: myapp_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20230206140511  Create tasks
   up     20231230034411  Create items
   up     20231230085325  Create active storage tablesactive storage
   up     20240101065120  Add image name to items
   up     20240117124127  Add detail to items
   up     20240204060936  Remove image name from items
   up     20240310104030  Create carts
   up     20240311124017  Create cart items
   up     20240502121245  Create checkouts
```

これで修正できました。


`STEP=X`をつけたすことで, 任意のところまでロールバックできます
以下は`order_summary`モデルをあとから作成した状態です。

```
$ rails db:migrate:status

database: myapp_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20230206140511  Create tasks
   up     20231230034411  Create items
   up     20231230085325  Create active storage tablesactive storage
   up     20240101065120  Add image name to items
   up     20240117124127  Add detail to items
   up     20240204060936  Remove image name from items
   up     20240310104030  Create carts
   up     20240311124017  Create cart items
   up     20240502121245  Create checkouts
   up     20240507115607  Create order summaries
```

`up     20240502121245  Create checkouts`のところまでロールバックする場合は以下のようになります

```
$ rails db:rollback STEP=2
== 20240507115607 CreateOrderSummaries: reverting =============================
-- drop_table(:order_summaries)
   -> 941.4622s
== 20240507115607 CreateOrderSummaries: reverted (941.5217s) ==================

== 20240502121245 CreateCheckouts: reverting ==================================
-- drop_table(:checkouts)
   -> 0.1185s
== 20240502121245 CreateCheckouts: reverted (0.1378s) =========================
```

最初の`order_summary`へのロールバックはご覧の通りかなり時間がかかりました
フリーズしたか？と思ってしまいました

```
$ rails db:migrate:status

database: myapp_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20230206140511  Create tasks
   up     20231230034411  Create items
   up     20231230085325  Create active storage tablesactive storage
   up     20240101065120  Add image name to items
   up     20240117124127  Add detail to items
   up     20240204060936  Remove image name from items
   up     20240310104030  Create carts
   up     20240311124017  Create cart items
  down    20240502121245  Create checkouts
  down    20240507115607  Create order summaries
```

2つ`down`にできました

### 参考
- [rails マイグレーションファイルの修正方法 #rails5.2 - Qiita](https://qiita.com/Futoshi_1229/items/a3b72782d206a7c6fe7b)