Squasher gem
こちらの gem です。Rails におけるマイグレーションファイルをまとめるための gem です。
インストールの方法
この gem を使うためにはもちろんインストールをする必要があります。公式ドキュメント では Rails のGemfile
に書く方法が紹介されています。
しかしながら、私は $ gem install squasher
によってユーザーグローバルにインストールしたほうがいいと思います。なぜなら、この gem を使う頻度を考えると、プロジェクトの共通の Gemfile
に書く必要性が薄いからです。依存関係により bundle install が失敗し*1、それの原因を探るために時間を費やすくらいならば初めから Gemfile
に書かないほうが良いと思っています。
単に Gemfile
はシンプルに必要最小限に保ちたいというのも理由です。
使い方
インストールしたらさっそく使ってみます。以下のコマンドの説明では、$ gem install squasher
を行ったものとします。Gemfile
に書いて bundle install をした場合は、$ squasher
の部分を $ bundle exec squasher
と置き換えてください。
0. 環境変数をコマンド実行時に指定しつつ実行する
$ gem install squasher
でインストールして Squasher を使う場合は、環境変数をコマンド実行時に指定します。dotenv-railse
は用いられないため、以下のように指定する必要があります。direnv
を使うのもいいでしょう。
$ POSTGRES_USER=foobar squasher --help
以後のコマンドの表記では、この環境変数を記述する部分は省略します。
1. 年月日を指定してマイグレーションファイルをまとめる
squasher
コマンドの引数に 年/月/日
を指定することで「指定年月日より以前の」マイグレーションファイルがまとまります。例えば、2020/03
と指定子た場合は、2020年2月を含む、それ以前のマイグレーションファイルがまとまります。
2. マイグレーションのバージョンを -m オプションを用いて指定する
任意のマイグレーションファイルの継承元である ActiveRecord::Migration
のバージョン番号を、squasher コマンドの -m オプションで指定します。
例えば、任意のマイグレーションファイルの冒頭に以下のように書いてあったとします。
class CreateHogeTable < ActiveRecord::Migration[6.0]
この場合、squasher
コマンドの -m
オプションには以下のように書きます。
$ squasher -m 6.0
3. コマンドの最終段階で出てくる 2つ の質問にどう答えるか
squasher
コマンド実行すると、最後に次のような質問が表示されます。
Squasher's created the `squasher` database for its needs. It might be useful to keep it if any of your deleted migrations inserts data or you squash migrations in a few steps (look at -r option). Keep it (yes / no)? yes Do you want to clean your database from the old schema migration records(yes/no)? no
Keep it (yes / no)?
の方は、yes
と答えると squasher
という名称でデータベースを作ってくれ、そこにコマンド実行前のデータベースのスキーマを構築しておいてくれます。バックアップ的なものと考えてよいでしょう。
Do you want to clean your database from the old schema migration records(yes/no)?
の方は、yes
と答えると、db:migrate:reset
を行います。つまり、既存のデータベースを drop して、db:migrate
をやり直します。レコードが消えてしまうので注意です。
補足
範囲を指定してまとめることはできません。つまり「ある地点より以前のファイルをまとめる」ことができるのみです。5年分のマイグレーションファイルがあるプロダクトにおいて、たとえば1年毎に1つのファイルにまとめて合計5ファイルにする、ということはできません*2。
このあたりは $ git rebase
で起きることがあるコンフリクトの嵐を考えれば、機能があることによる弊害は小さくないと思いますので、しょうがないかなと考えています。