Railsを使うときに、マイグレーションは便利ですが、戻すときのことまで考えて実装していますでしょうか。
bin/rails db:rollback
bin/rails db:migrateでマイグレーションを実行できますが、逆にbin/rails db:rollbackで戻すこともできます。ただし、マイグレーションが戻ることを前提にしている必要があります。
考えなくて良いパターン
create_tableやadd_columnなど追加系のメソッドをchangeに書いていた場合、逆向きは「追加したものを削除する」ことが明らかですので、自分で書かなくても対応してくれます。
戻し方を書けば対応してくれるパターン
drop_tableやremove_columnを行う場合、ただ削除する内容を書くだけでは、戻し方がわかりません。そこで、これらのメソッドはcreate_tableやadd_columnと同様に元の定義を書けるようになっています。ロールバック時にはそれが使われます。
戻さない・戻せないパターン
たとえば、NULLの列をNOT NULLに変えるとか、utf8だった列をutf8mb4に入れ替えるとか、intの列をstringに変えるとか、値域を広げる方向にマイグレーションをかけた場合、元に戻そうにも広がった後のデータが入らないことがあるので、戻しようがありません。
このような場合はupだけ書いて、downはraise ActiveRecord::IrreversibleMigrationとすることで、「戻せない」ことをコードで明示できます。
また、現実問題としてデプロイ後にマイグレーションをロールバックするような運用は通常行いませんので、ある程度以上複雑なマイグレーションを書いた場合に、戻す方まで厳密に書かずにraise ActiveRecord::IrreversibleMigrationで済ます、という手段も、状況によってはありかもしれません。
戻す側が不要になる場合
時には、戻す側で何もしなくていいことがあります。たとえば、「あるカラムに空文字列とNULLが混在しているので、全てを一方に揃える」というようなマイグレーションを立てたとします。これのdown側は、特に何もしなくても元のデータと整合するので、放置して構いません。このような場合、
def down
# 戻す側で何もしなくていい理由
end
のように、コメントで間違いではないことを明記しておきましょう。