マイグレーションファイルやテーブルの削除手順書


Railsを使い始めた頃に、マイグレーションファイルの扱いに苦戦していた時がありました。
手順や状態の確認もしないまま「いらないマイグレーションだから消してしまえ!」とか...

部分的なコマンドだけではなく、「実際の流れ」や「意図」を交えて書いていきます。
スクショも使ってあるので、見難かったらすみません...汗
$ は入力しなくても大丈夫です!

はじめにマイグレーションファイルの状態を確認します

プロジェクト内のターミナルで下記を実行

$ rails db:migrate:status

すると、現在実行されているマイグレーションファイルの状態が分かります。

※ 行いたい事:
一番下にあるCreate text matelialsのマイグレーションファイルで作成したテーブルを削除してからマイグレーションファイルも削除したい時の説明です。

1: Statusの状態を確認する

左側のStatusは全てupになっています。

upになっているということはデータベースは、このマイグレーションファイルの構造を取り入れている(マイグレーションファイルはすでに実行済みのファイル)ということです。
up状態のマイグレーションファイルは削除したり編集したりしてはいけません。

状態がわかったので次は、

2: upをdownを切り替える方法

ここで必要な情報は Migration ID の数字!!
今回で言うと20200608181608です。

プロジェクト内のターミナルで下記を実行

$ rails db:migrate:down VERSION= "Migration ID"

今回だと下記になります。

$ rails db:migrate:down VERSION=20200608181608

すると、こんな画面になる。
エラーが出なければOKです!

もう一度Statusを確認します
rails db:migrate:statusを実行


ちゃんとdownになっています。
down状態なので編集と削除ができます。

3: テーブルを編集、削除する手順

"db/maigrate"内にあるマイグレーションファイルを開いて追記します。

(↑ は後に重要なことなので、太めに書いておきました)

今回は、"db/maigrate"内にある
20200608181608_create_text_matelials.rbファイルを開きます。

中のコードが下記の時

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

この中へ drop_table :削除したいテーブル名 を追記します。
※自身のテーブル名を確認したい場合はdb/schema.rbの中を確認してください。
※注意:ActiveRecord::Migration [6.0] の部分は自身のRailsのバージョンに指定してください。(例) [5.1]

「Railsのバージョンがわからない...」場合は
ターミナルでrails -vを実行するとわかりますよ。

追記後は下記です。

class CreateTextMatelials < ActiveRecord::Migration[6.0]
  def change
    drop_table :text_matelials
  end
end

削除する追記が完了したらrails db:migrateを実行します。
これでテーブルの削除ができました。

db/schema.rbの中を確認すると指定したテーブルは削除されているはずです。

【何が起きていたのか文章で言うと..】
drop_table :text_matelialsとしてtext_matelialsテーブルを削除する内容を記述したファイルを実行したのでテーブルを削除できたというわけです。
rails db:migrate:statusでステータスを確認してみると
rails db:migrateを実行したのでStatusの状態はupになっています。
こんな感じでしょうか..

引き続き"マイグレーションファイルの削除"を説明します。

4: マイグレーションファイルを削除する手順

今は、
"db/maigrate"内にある
20200608181608_create_text_matelials.rbファイルをこのまま削除する方法です。

プロジェクト内のターミナルで下記を実行

$ rm -rf db/migrate/20200608181608_create_text_matelials.rb

rails db:migrate:statusを実行して、ステータスを確認してください。
削除されていることがわかると思います。

5: マイグレーションを間違って削除してしまった場合

データベースに反映したマイグレーションファイルを不要だと思い、誤って削除した時にrails db:migrate:statusを実行してステータスを確認すると下のように"NO FILE"と出てきてしまった時の対処です。

手順に入る前になぜNO FILE になっているのか状況を説明します。

【 NO FILE になっている状況の説明 】

上の画面から分かることはStatusが NO FILE となっているマイグレーションがupになっている!
ということはデータベースはこのマイグレーションファイルの構造を取り入れているということですね。

up状態のマイグレーションファイルを手動でカラムの削除したり、カラムを使っていないということでマイグレーションファイルを削除したのかもしれません。

NO FILE になるのは、
マイグレーションファイルを削除してもdb/migration内のschema_migrationsテーブルにバージョンが保存されているためです。

schema_migrationsテーブルから削除してしまったマイグレーションファイルのバージョンが保存されているレコードを削除すればこの表示は消えます。

※ 単にdb/migration/schema.rbの内部を削除しただけでは
rails db:migrateするとまた復活してしまいます。

6: NO FILE状態のschema.rb内のテーブルとNO FILEを削除する手順

[3: テーブルを編集、削除する手順]で説明したように

"db/maigrate"内にあるマイグレーションファイルを開いて追記が必要

ですが、今回の場合はマイグレーションファイルが無いので、マイグレーションファイルを作成するところからはじめます。

はじめにrails db:migrate:statusを実行してMigration ID を確認しましょう。

今回だと20200601140204になります。

マイグレーションファイルを作成する

rails プロジェクトの db/migrateに移動
プロジェクト内のターミナルで下記を実行

$ cd db/migrate

マイグレーションファイルを作成します。

db/schema.rbの中でテーブルを確認した時に、
今回はconversationsテーブルを削除したい。とすると
touch マイグレーションID_ファイル名.rb
(※最終的に削除します。一時的な使用なのでのでファイル名はなんでも構いません)
(※もしテーブルを使いたい場合は、適した名前にしてください)

今回は下記のようにしました
プロジェクト内のターミナルで実行

$ touch 20200601140204_tmp.rb

これでtmp.rbというマイグレーションファイルができました。
次に
[3: テーブルを編集、削除する手順]
[4: マイグレーションファイルを削除する手順]
を行います。

...と省略されると不安に思う人(自分..)もいると思うので、ダブりますが続きも書いておきますね。

テーブルを編集、削除する

エディタからdb/migrate内の
20200601140204_tmp.rbファイルを開いて下記を記述
※注意:ActiveRecord::Migration [6.0] の部分は自身のRailsのバージョンに指定します。(例) [5.1]
「Railsのバージョンがわからない...」場合は
ターミナルでrails -vを実行するとわかります。

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

schema.rb内にテーブルを作成していないファイルならこのまま削除しますが今回は先ほど作成したマイグレーションファイルを使ってschema.rb内のテーブルを削除したいので更に drop_table :削除したいテーブル名 を追記します。

※テーブル名を確認したい場合はdb/schema.rbの中を確認。

今回はconversationsテーブルを削除したいとします。

class CreateConversations < ActiveRecord::Migration[6.0]
  def change
    drop_table :conversations
  end
end

編集が終了したので
rails db:migrateをしてテーブルを削除します。

db/schema.rbの中を確認すると指定したテーブルが削除されていると思います。

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

残るは先ほどNOFILE状態だったファイル(現在の 20200601140204_tmp.rb)ですね。

まずはup状態をdown状態にします!!...と
その前にdrop_table :conversationsがあるとdownできないので削除しておきましょう。

down状態にするのに必要な情報は Migration ID の数字です。
今回で言うと20200601140204ですね。

プロジェクト内のターミナルで下記を実行

$ rails db:migrate:down VERSION=20200601140204

rails db:migrate:statusを実行してステータスを確認。
downになっていればOKです!

"db/maigrate"内にある
20200601140204_tmp.rbファイルをこのまま削除します。

プロジェクト内のターミナルで下記を実行

$ rm -rf db/migrate/20200601140204_tmp.rb

ステータスを確認
rails db:migrate:statusを実行
するとはじめにNOFILEだったものも削除されていることがわかるります!

自分も経験した勘違い

サーバーにアップされた時に、マイグレーションファイルは全てdown状態なのでrails db:migrateコマンドを実行します。

例えばusersテーブルを作成するマイグレーションファイルを削除してしまって、その後にusersテーブルにカラムを追加するマイグレーションファイルがあった時、存在しないusersテーブルにカラムを追加することはできないのでエラーが出てしまいます。

ローカルではエラーは出ないのに、サーバーにアップしたらなぜかエラーになる...
こんな状況になるときがありました。

ローカル環境ではusersテーブルが削除される前にrails db:migrateで実行してありマイグレーションファイルによって既に作成されているので、マイグレーションファイルを誤って削除してしまった場合でもエラーが出ない。
ただ、
サーバーにアップされた時は、マイグレーションファイルは全てdown状態になっているのでrails db:migrateコマンドを実行することになります。

でも、usersテーブルを作成するマイグレーションファイルを削除してしまっている状態では存在しないusersテーブルにカラムを追加することはできないぞ!とエラーが出てしまう。

「ローカルとサーバーにアップした時で上記のような齟齬がないようにするため」と、
「チーム開発している場合に、他の開発者を混乱させる要員になる」ので注意して行う。
マイグレーションファイルを削除する際は必ずdown状態になっているのを確認してから編集や削除する!ということを忘れないようにしたいですね。

手動で削除してしまえばいいだろ!とはいかないのです。

最後に

意味がわからない..と焦りますよね。
私もそうです。(現在進行形)笑
今回は長くなってしまいましたが、「コマンドだけ」とか「ここを参考」とかをあえて使わず、内容ダブってもいいから書こう!その方が流れが分かりやすいと思い書きました。

初学者目線だと「流れ」が分かれば、理解は早いと感じてます。
少しでも参考になれば嬉しいです!

間違い等ございましたら、勉強して修正させて頂きますのでご指摘ください!
以上です。おつかれさまでした!