123456789_123456789_123456789_123456789_123456789_

Class: ActiveRecord::MigrationContext

Relationships & Source Files
Inherits: Object
Defined in: activerecord/lib/active_record/migration.rb

Overview

Migration Context

MigrationContext sets the context in which a migration is run.

A migration context requires the path to the migrations is set in the #migrations_paths parameter. Optionally a #schema_migration class can be provided. Multiple database applications will instantiate a SchemaMigration object per database. From the Rake tasks, Rails will handle this for you.

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(migrations_paths, schema_migration = nil, internal_metadata = nil) ⇒ MigrationContext

[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1205

def initialize(migrations_paths, schema_migration = nil,  = nil)
  if schema_migration == SchemaMigration
    ActiveRecord.deprecator.warn(<<-MSG.squish)
      SchemaMigration no longer inherits from ActiveRecord::Base. If you want
      to use the default connection, remove this argument. If you want to use a
      specific connection, instantiate MigrationContext with the connection's schema
      migration, for example `MigrationContext.new(path, Dog.connection.schema_migration)`.
    MSG

    schema_migration = nil
  end

  if  == InternalMetadata
    ActiveRecord.deprecator.warn(<<-MSG.squish)
      SchemaMigration no longer inherits from ActiveRecord::Base. If you want
      to use the default connection, remove this argument. If you want to use a
      specific connection, instantiate MigrationContext with the connection's internal
      metadata, for example `MigrationContext.new(path, nil, Dog.connection.internal_metadata)`.
    MSG

     = nil
  end

  @migrations_paths = migrations_paths
  @schema_migration = schema_migration || SchemaMigration.new(connection)
  @internal_metadata =  || InternalMetadata.new(connection)
end

Instance Attribute Details

#internal_metadata (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1203

attr_reader :migrations_paths, :schema_migration, :

#migrations_paths (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1203

attr_reader :migrations_paths, :schema_migration, :

#needs_migration?Boolean (readonly)

This method is for internal use only.
[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1308

def needs_migration? # :nodoc:
  pending_migration_versions.size > 0
end

#protected_environment?Boolean (readonly)

This method is for internal use only.
[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1351

def protected_environment? # :nodoc:
  ActiveRecord::Base.protected_environments.include?(last_stored_environment) if last_stored_environment
end

#schema_migration (readonly)

[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1203

attr_reader :migrations_paths, :schema_migration, :

Instance Method Details

#connection (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1366

def connection
  ActiveRecord::Tasks::DatabaseTasks.migration_connection
end

#current_environment

This method is for internal use only.
[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1347

def current_environment # :nodoc:
  ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
end

#current_version

This method is for internal use only.
[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1303

def current_version # :nodoc:
  get_all_versions.max || 0
rescue ActiveRecord::NoDatabaseError
end

#down(target_version = nil, &block)

This method is for internal use only.
[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1277

def down(target_version = nil, &block) # :nodoc:
  selected_migrations = if block_given?
    migrations.select(&block)
  else
    migrations
  end

  Migrator.new(:down, selected_migrations, schema_migration, , target_version).migrate
end

#forward(steps = 1)

This method is for internal use only.
[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1263

def forward(steps = 1) # :nodoc:
  move(:up, steps)
end

#get_all_versions

This method is for internal use only.
[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1295

def get_all_versions # :nodoc:
  if schema_migration.table_exists?
    schema_migration.integer_versions
  else
    []
  end
end

#last_stored_environment

This method is for internal use only.
[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1355

def last_stored_environment # :nodoc:
  return nil unless connection..enabled?
  return nil if current_version == 0
  raise NoEnvironmentInSchemaError unless connection..table_exists?

  environment = connection.[:environment]
  raise NoEnvironmentInSchemaError unless environment
  environment
end

#migrate(target_version = nil, &block)

Runs the migrations in the migrations_path.

If target_version is nil, migrate will run #up.

If the #current_version and target_version are both 0 then an empty array will be returned and no migrations will be run.

If the #current_version in the schema is greater than the target_version, then #down will be run.

If none of the conditions are met, #up will be run with the target_version.

[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1246

def migrate(target_version = nil, &block)
  case
  when target_version.nil?
    up(target_version, &block)
  when current_version == 0 && target_version == 0
    []
  when current_version > target_version
    down(target_version, &block)
  else
    up(target_version, &block)
  end
end

#migration_files (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1370

def migration_files
  paths = Array(migrations_paths)
  Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
end

#migrations

This method is for internal use only.
[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1316

def migrations # :nodoc:
  migrations = migration_files.map do |file|
    version, name, scope = parse_migration_filename(file)
    raise IllegalMigrationNameError.new(file) unless version
    version = version.to_i
    name = name.camelize

    MigrationProxy.new(name, version, file, scope)
  end

  migrations.sort_by(&:version)
end

#migrations_status

This method is for internal use only.
[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1329

def migrations_status # :nodoc:
  db_list = schema_migration.normalized_versions

  file_list = migration_files.filter_map do |file|
    version, name, scope = parse_migration_filename(file)
    raise IllegalMigrationNameError.new(file) unless version
    version = schema_migration.normalize_migration_number(version)
    status = db_list.delete(version) ? "up" : "down"
    [status, version, (name + scope).humanize]
  end

  db_list.map! do |version|
    ["up", version, "********** NO FILE **********"]
  end

  (db_list + file_list).sort_by { |_, version, _| version.to_i }
end

#move(direction, steps) (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1379

def move(direction, steps)
  migrator = Migrator.new(direction, migrations, schema_migration, )

  if current_version != 0 && !migrator.current_migration
    raise UnknownMigrationVersionError.new(current_version)
  end

  start_index =
    if current_version == 0
      0
    else
      migrator.migrations.index(migrator.current_migration)
    end

  finish = migrator.migrations[start_index + steps]
  version = finish ? finish.version : 0
  public_send(direction, version)
end

#open

This method is for internal use only.
[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1291

def open # :nodoc:
  Migrator.new(:up, migrations, schema_migration, )
end

#parse_migration_filename(filename) (private)

[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1375

def parse_migration_filename(filename)
  File.basename(filename).scan(Migration::MigrationFilenameRegexp).first
end

#pending_migration_versions

This method is for internal use only.
[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1312

def pending_migration_versions # :nodoc:
  migrations.collect(&:version) - get_all_versions
end

#rollback(steps = 1)

This method is for internal use only.
[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1259

def rollback(steps = 1) # :nodoc:
  move(:down, steps)
end

#run(direction, target_version)

This method is for internal use only.
[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1287

def run(direction, target_version) # :nodoc:
  Migrator.new(direction, migrations, schema_migration, , target_version).run
end

#up(target_version = nil, &block)

This method is for internal use only.
[ GitHub ]

  
# File 'activerecord/lib/active_record/migration.rb', line 1267

def up(target_version = nil, &block) # :nodoc:
  selected_migrations = if block_given?
    migrations.select(&block)
  else
    migrations
  end

  Migrator.new(:up, selected_migrations, schema_migration, , target_version).migrate
end