rails db:rollbackは取り扱い注意⚠️

Created: 2025/02/22

この記事は、rails db:rollbackの扱い方について考察する内容です。
私は現在、Ruby on Railsを利用してチーム開発を行っています。その際に、rails db:rollbackがどいう時に有効なのか、また致命的な損傷を起こすのかという点が気になりまとめました。
特にチーム開発では、rails db:rollbackを実行することで致命的な不具合を起こす可能性があるので理解しておきたいので記事にしました。

Rollbackとは?

まず、RollbackとはITの用語であり、システムに障害や不具合が生じた場合、以前の正常な状態に戻すこと指します。

rails db:rollbackとは?

このrails db:rollbackも似たような機能になります。これは、主にDB(データベース)の状態を戻す際に利用します。

マイグレーションについて

Ruby on Railsでは「マイグレーション」という機能を利用し、SQL文を書かずにDBにテーブルやカラムの追加、削除、修正が可能です。
マイグレーションを実行する際は、マイグレーションファイルを作ります。

例えば

20240502100843_create_products.rb
1
2
3
4
5
6
7
8
9
10
11
# db/migrate/20240502100843_create_products.rb
class CreateProducts < ActiveRecord::Migration[8.0]
  def change
    create_table :products do |t|
      t.string :name
      t.text :description

      t.timestamps
    end
  end
end

上記のようなファイルを作成して、rails db:migrateというコマンドを実行することでDBに新たなテーブルとカラムが追加されます。これをマイグレーションファイルがupの状態と言います。
例では、2つのnamedescriptionのカラムを持った、Productsというテーブルが作成されます。そして、20240502100843_create_products.rbファイルがupの状態になります。

マイグレーションの仕様上、一度rails db:migrateを実行してDBに反映し、upの状態にすると20240502100843_create_products.rbを修正して、再度rails db:migrateを実行しても修正内容は反映されません。そんな時にrails db:rollbackを利用します。

rails db:rollbackを実行すると、一つ前のマイグレーションをupの状態からdownの状態にできます。このdown状態になると20240502100843_create_products.rbの内容が取り消しになります。つまり、DBからProductsテーブルが削除されます。そのため、upの状態で、Productsテーブルに何かデータを保存した後にdown状態にすると保存したデータが消えます。
*マイグレーションファイルがupかdownはrails db:migrate:statusで確認できます。

rails db:rollback の取り扱い方

ここからが本題です。前述のように、rails db:rollbackはDBに変更を加える操作なので慎重に行う必要があります。
もし不用意にrollbackを実行すると、チームメンバーの作業に影響を与えたり、最悪の場合、本番環境のデータを破壊してしまうリスクがあります。
そこで、チーム開発におけるrollbackの取り扱いを 3つのケースに分けて考察します。

  1. ローカルのブランチの場合(プッシュ前)
  2. リモートブランチで共有されている場合(プッシュ後)⚠️
  3. すでに本番環境でデプロイしてある場合 🚨

この3ケースあると考えられます。

ローカルのブランチの場合(プッシュ前)

結論:rails db:rollbackは行って大丈夫です🙆
ローカルのブランチ、つまり、自分のブランチということです。自分のブランチということでrails db:rollbackを実行してもチームのメンバーに影響はありません。
しかし、注意点が一つあります。それは、本番環境でマイグレーションされているファイルを編集してはいけないことです。

例)

./db/migrate
20240502100843_create_products.rb ← デプロイ済みファイル
20240503100842_create_users.rb ← ローカルで追加したファイル

ローカルで追加したファイルは、自由にrails db:rollbackを行い修正しても問題ありません。しかし、デプロイ済みファイルrails db:rollbackしてを修正してrails db:migrateを実行するとマイグレーションの履歴が変更されます。その状態でプシュしてデプロイするとエラーが発生します。そのため、本番環境でrails db:rollback実行する必要があります。つまり、本番環境であるProductsテーブルのデータが消えます。
なので、デプロイ済みのマイグレーションファイルは編集しないように注意しましょう!

対策

もしデプロイ済みマイグレーションファイルの内容を修正したい場合は新しいマイグレーションファイルを作成して対応できます!

リモートブランチで共有されている場合(プッシュ後)⚠️

結論:他のメンバーに影響があるので、慎重にrails db:rollbackする必要がある
私はこのケースでrails db:rollbackをすべきか迷いました。
私の場合マイグレーションファイルが増えてきたので一度マイグレーションファイルに不備がないか確かめて不具合があればマイグレーションをやり直そうとしました。しかし、ケース1で説明した様にすでにデプロイ済みマイグレーションファイルを修正すると本番環境でのマイグレーション履歴とずれが生じるため危険です。
一方、プッシュだけして本番環境にデプロイしていないマイグレーションファイルに不具合がありました。例を出します。

例)

20240502100843_create_products.rb ← デプロイ済みファイル
20240503100842_create_users.rb ← プッシュされたファイル(デプロイ前)

プッシュされたファイル(デプロイ前)が不具合や内容を修正したいとします。その場合、新しくマイグレーションファイル作り内容を修正してもいいです。しかし、それでは余分なマイグレーションファイルが作成され、不具合があるマイグレーションファイルがある状態です。そもためコードの品質を高めるためにも本番環境でのデプロイ前のものであれば、rails db:rollbackを実行してマイグレーションファイルを修正しても良いと考えています。

注意点

プッシュされたマイグレーション(デプロイ前)を修正した場合、そのブランチをプルしてrails db:migrateしたメンバーのマイグレーション履歴とずれが生じるため、一度rails db:rollbackをしてマイグレーションの履歴を揃える必要がありあます。rails db:rollbackをした際はチームのメンバーに修正を共有するようにしましょう!

すでに本番環境でデプロイしてある場合 🚨

最後はケース3です。
結論としては、rails db:rollbackするのは非常に危険です。
本番環境で実行されているマイグレーションファイルを修正すると本番で保存されているデータが破損する恐れがあります。

解決案

今ままでのケースの様に新しくマイグレーションファイルを作成することで対応できます。
私も一度、本番環境で実行されているファイルまで修正しようと考えていましたがケース2までの対応でとどまりました。

最終手段

どうしても、本番環境でマイグレーションファイルをrails db:rollbackして修正した場合はDBをバックアップ取り修正する必要があると思います。

参考