😀

VERSION指定を添えたマイグレーションの一覧を表示するRakeタスク

に公開

やりたいこと

./bin/rails db:migrate 実行時に VERSION を指定して実行することで、指定したマイグレーションだけ実行することができる。
実行対象のversionを db:migrate:status で確認してもよいが、コマンドの候補を一覧として表示することで、より手軽に実行させたい。

ActiveRecord::Migratoin#pending_migrations

privateメソッドの ActiveRecord::Migratoin#pending_migrations が以下のようになっている。

def pending_migrations
  pending_migrations = []

  ActiveRecord::Base.configurations.configs_for(env_name: env).each do |db_config|
    ActiveRecord::PendingMigrationConnection.with_temporary_pool(db_config) do |pool|
      if pending = pool.migration_context.open.pending_migrations
        pending_migrations << pending
      end
    end
  end

  pending_migrations.flatten
end

これを参考に一覧を出力するコマンドを作る。

出力するRakeタスク db:hint

version情報を添えて ./bin/rails db:migrate を出力する。
どのversionがどのマイグレーションかを判断しやすくするため、nameも添えて出力する。

Rakefile
namespace :db do
  task hint: :environment do
    pending_migrations = []
    ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).each do |db_config|
      ActiveRecord::PendingMigrationConnection.with_temporary_pool(db_config) do |pool|
        if pending = pool.migration_context.open.pending_migrations
          pending_migrations << pending
        end
      end
    end

    pending_migrations.flatten.each do |migration|
      puts "./bin/rails db:migrate VERSION=#{migration.version}  # #{migration.name}"
    end
  end
end

実行例

$ ./bin/rails db:hint
./bin/rails db:migrate VERSION=20250520151122  # CreateUsers
./bin/rails db:migrate VERSION=20250522141943  # CreateHoges

補足

Multi DB環境を考慮する場合は db_config のところでgroup_byでグループ化して出力を調整する。

Discussion