開発環境
言語:Ruby (2.7.2)
フレームワーク:Ruby on Rails (6.1.3.2)
フロントエンド:HTML&CSS/Bootstrap/JavaScript/jQuey
DB:PostgreSQL
背景
新規でマイグレーションファイルを作成し、データベースにテンプレート文を入れる方法がわかりました。
テスト的に作ったマイグレーションファイルが不要担ったため、ロールバックしたところできなくなったため共有します。
解決方法
ロールバック実施
$ rails db:rollback
エラー発生!!
% rails db:rollback
== 20210917010552 ChangeColumnDefaultSolutionOfIncidents3: reverting ==========
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:
This migration uses change_column, which is not automatically reversible.
To make the migration reversible you can either:
1. Define #up and #down methods in place of the #change method.
2. Use the #reversible method to define reversible behavior.
/Users/koyoishikawa/インシデントアプリ/incident_app/db/migrate/20210917010552_change_column_default_solution_of_incidents3.rb:3:in `change'
/Users/koyoishikawa/インシデントアプリ/incident_app/bin/rails:5:in `<top (required)>'
/Users/koyoishikawa/インシデントアプリ/incident_app/bin/spring:10:in `block in <top (required)>'
/Users/koyoishikawa/インシデントアプリ/incident_app/bin/spring:7:in `tap'
/Users/koyoishikawa/インシデントアプリ/incident_app/bin/spring:7:in `<top (required)>'
Caused by:
ActiveRecord::IrreversibleMigration:
This migration uses change_column, which is not automatically reversible.
To make the migration reversible you can either:
1. Define #up and #down methods in place of the #change method.
2. Use the #reversible method to define reversible behavior.
/Users/koyoishikawa/インシデントアプリ/incident_app/db/migrate/20210917010552_change_column_default_solution_of_incidents3.rb:3:in `change'
/Users/koyoishikawa/インシデントアプリ/incident_app/bin/rails:5:in `<top (required)>'
/Users/koyoishikawa/インシデントアプリ/incident_app/bin/spring:10:in `block in <top (required)>'
/Users/koyoishikawa/インシデントアプリ/incident_app/bin/spring:7:in `tap'
/Users/koyoishikawa/インシデントアプリ/incident_app/bin/spring:7:in `<top (required)>'
Tasks: TOP => db:rollback
(See full trace by running task with --trace)
多分ここでなんか言っている
Caused by:
ActiveRecord::IrreversibleMigration:
This migration uses change_column, which is not automatically reversible.
To make the migration reversible you can either:
1. Define #up and #down methods in place of the #change method.
2. Use the #reversible method to define reversible behavior.
翻訳すると
📌 以下のせいで: ActiveRecord :: 不可逆移行エラー:この移行ではchange_columnを使用しますが、これは自動的に元に戻すことはできません。
移行をリバーシブルにするには、次のいずれかを実行できます。
- #changeメソッドの代わりに#upメソッドと#downメソッドを定義します。
- #reversibleメソッドを使用して、可逆的な動作を定義します。
多分#upメソッドと#downメソッドを使え!という意味だと思い、色々と調べた。
自分の知っている中ではステータスがupのマイグレーションファイルはいじってはいけない!!という思い込みがあったため調査に時間がかかった。
結論:ステータスをdownにしてからであればマイグレーションファイルはいじっても良い
そもそもup状態のマイグレーションファイルをいじったところでスキーマに反映済みであるため、いじっても意味がないし、
いじってからrails db:migrateを実行しても反映済み(up状態)のマイグレーションファイルはもう一度スキーマに反映されない。
そのためロールバックしステータスをdownにして、マイグレーションファイルを編集後rails db:migrateを実行するとスキーマに反映される
以下記事を参考にマイグレーションファイルを修正後ロールバックを実施。
マイグレーションファイルの修正
class ChangeColumnDefaultSolutionOfIncidents < ActiveRecord::Migration[6.1]
def change
change_column :incidents, :solution, :text, null: false, default: "解決方法"
end
end
のcahnge
メソッドをup
メソッドに変更後、ロールバックを実行。
class ChangeColumnDefaultSolutionOfIncidents < ActiveRecord::Migration[6.1]
def up
change_column :incidents, :solution, :text, null: false, default: "解決方法"
end
end
% rails db:rollback
== 20210917010552 ChangeColumnDefaultSolutionOfIncidents3: reverting ==========
== 20210917010552 ChangeColumnDefaultSolutionOfIncidents3: reverted (0.0002s) =rails db:rollback
うまくいきました。
そもそもchenge up・downとはなんぞやという方は以下参照
【Ruby on Rails】changeとup・downの使い分けについて - Qiita
簡単に言うと
up
メソッドはマイグレーションファイルをupのときの処理(rails db:migrate で動く)
down
メソッドはマイグレーションファイルがdownのときの処理(rails db:rollback で動く)
change
メソッドは変更を加えるときの処理
どれも変更を加えるときに使われるが、使い分けは
・テーブルの形を変えるとき(カラムを追加するとき)はchange
・カラムの情報を変えるとき(今回はdefault値を追加)up・downを利用する
以上です
参考資料
マイグレーションファイルを徹底解説!
railsで特定のマイグレーションファイルをロールバックする - Qiita
Active Record マイグレーション - Railsガイド