Rails マイグレーションファイルを削除したためにロールバックができない

もくもく会に参加

9月13日、オンラインで Web初学者のリモートもくもく会 from 鹿児島 #3 に参加した。フィヨルドブートキャンプで企業研修をされていた方が主催のもくもく会で、これまで毎回参加させてもらっている。

昨日のハッシュの問題の続きをやるつもりだったが、せっかくの機会なのでここ数日悩んでいたところを質問させてもらった。

マイグレーションファイルを削除したためにロールバックができない

解決策 やったこと

(9月17日追記)以下の内容はよい方法ではない可能性があるので、安易に真似しない方がいいかもしれない(現在調査中)

  1. 削除したマイグレーションファイルと同じ ID のマイグレーションファイルを作る
  2. ロールバック実行
  3. 作ったマイグレーションファイルを削除

(参考)railsのrakeのmigrationファイルを削除しNO FILEとstatusに出た時の対処 – joppot

質問に至るまでの経過

パーフェクト Ruby on Rails 【増補改訂版】 の内容に合わせて、勉強用の Rails アプリを作っていた。ちょっと試したいことがあって、本に関係ない User というモデルを作った。

具体的には、bin/rails g model User name:string age:integer してから、bin/rails db:migrate を実行した。

その後 User モデルでいろいろ試してみてから、用が済んだので bin/rails d model User を実行して User モデルを削除。

データベースから users テーブルを削除するためにロールバックしようとしたところ、マイグレーションファイルがないためエラーに。

実際にやったこと

削除してしまったマイグレーションファイルの ID を確認。

$ bin/rails db:migrate:status

database: db/development.sqlite3

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200829235003  Create books
   up     20200830010456  Create publishers
   up     20200830010535  Create authors
   up     20200901141549  ********** NO FILE **********

NO FILE となっているのが削除したファイルなので、その Migration ID をコピー。

削除したファイルと同じ ID のマイグレーションファイルを作る。ID が同じであれば、それ以降はなんでもいいようだ。

例)20200901141549_dummy.rb

$ code db/migrate/20200901141549_create_users.rb

codeVSCode でファイルを編集・作成するコマンド)

ファイルの中身は適当。

class CreateUsers < ActiveRecord::Migration[6.0]
  def change
  end
end

ロールバックを実行。

$ bin/rails db:rollback
== 20200901141549 CreateUsers: reverting ======================================
-- drop_table(:users)
   -> 0.0023s
== 20200901141549 CreateUsers: reverted (0.0063s) =============================

ロールバックできた!

$ bin/rails db:migrate:status

database: db/development.sqlite3

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200829235003  Create books
   up     20200830010456  Create publishers
   up     20200830010535  Create authors
  down    20200901141549  Create users

down になっていることを確認。

マイグレーションファイルを削除。

$ rm db/migrate/20200901141549_create_users.rb 

再度 status を見てみる。

$ bin/rails db:migrate:status

database: db/development.sqlite3

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200829235003  Create books
   up     20200830010456  Create publishers
   up     20200830010535  Create authors

schema.rb を見ると users テーブルがなくなっていることを確認できた。

本来は、User モデルを削除する前にロールバックしておくのが正しいやり方。

それから、Git で管理していればもっと簡単に User モデルを作る前の状態に戻せたはずなので、今日コミットした。