Module: RailsAiContext::MigrationStatus

Defined in:
lib/rails_ai_context/migration_status.rb

Overview

Resolves pending-migration status the same way Rails itself does for the "Migrations are pending" dev error page (ActiveRecord::Migration.check_pending! walks pool.migration_context.open.pending_migrations). MigrationContext moved from the connection object to the connection pool between Rails 7.0 and 7.1, and ActiveRecord::Migrator.new's signature changed to require a schema_migration

  • internal_metadata pair it can no longer build on its own - so a single hardcoded construction path breaks on part of the range this gem supports. The respond_to? cascade below picks whichever construction the loaded ActiveRecord version actually exposes instead of guessing from a version number.

Class Method Summary collapse

Class Method Details

.migration_context(migrate_dir) ⇒ ActiveRecord::MigrationContext

Returns:

  • (ActiveRecord::MigrationContext)


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/rails_ai_context/migration_status.rb', line 31

def self.migration_context(migrate_dir)
  pool = ActiveRecord::Base.connection_pool

  # Rails 7.1+: MigrationContext takes a schema_migration + internal_metadata
  # pair (per-connection bookkeeping objects) that only the pool knows how
  # to build - construct explicitly with OUR migrate_dir rather than
  # calling pool.migration_context directly, since that resolves its own
  # migrations_paths relative to the process's working directory, which
  # isn't guaranteed to equal Rails.root (daemonized servers, this gem's
  # own test suite).
  if pool.respond_to?(:schema_migration) && pool.respond_to?(:internal_metadata)
    return ActiveRecord::MigrationContext.new(migrate_dir, pool.schema_migration, pool.)
  end

  # Rails 7.0: MigrationContext.new(migrations_paths, schema_migration =
  # SchemaMigration) - construct with OUR migrate_dir for the same reason
  # as above. The connection's own migration_context resolves the app's
  # configured migrations_paths and ignores the directory being asked
  # about, silently reporting zero pending migrations.
  ActiveRecord::MigrationContext.new(migrate_dir)
end

.pending(migrate_dir) ⇒ Array<Hash>?

Returns [{ version:, name: }, ...] in pending order, or nil when pending status can't be determined (no migrations directory, ActiveRecord not loaded, or the database is unreachable).

Parameters:

  • migrate_dir (String)

    path to the migrations directory to check

Returns:

  • (Array<Hash>, nil)

    [{ version:, name: }, ...] in pending order, or nil when pending status can't be determined (no migrations directory, ActiveRecord not loaded, or the database is unreachable).



19
20
21
22
23
24
25
26
27
28
# File 'lib/rails_ai_context/migration_status.rb', line 19

def self.pending(migrate_dir)
  return nil unless migrate_dir && Dir.exist?(migrate_dir)
  return nil unless defined?(ActiveRecord::Base)

  context = migration_context(migrate_dir)
  context.open.pending_migrations.map { |m| { version: m.version.to_s, name: m.name } }
rescue => e
  $stderr.puts "[rails-ai-context] MigrationStatus.pending failed: #{e.message}" if ENV["DEBUG"]
  nil
end