Added MigrationProxy to defer loading of Migration classes until they are actually required by the migrator

Signed-off-by: Michael Koziarski <michael@koziarski.com>
[#747 state:resolved]
This commit is contained in:
Nik Wakelin 2008-08-02 17:44:02 +12:00 committed by Michael Koziarski
parent 29a06f10e8
commit 0809747845
2 changed files with 46 additions and 6 deletions

View File

@ -349,6 +349,27 @@ module ActiveRecord
end
end
# MigrationProxy is used to defer loading of the actual migration classes
# until they are needed
class MigrationProxy
attr_accessor :name, :version, :filename
delegate :migrate, :announce, :write, :to=>:migration
private
def migration
@migration ||= load_migration
end
def load_migration
load(filename)
name.constantize
end
end
class Migrator#:nodoc:
class << self
def migrate(migrations_path, target_version = nil)
@ -437,7 +458,7 @@ module ActiveRecord
runnable.pop if down? && !target.nil?
runnable.each do |migration|
Base.logger.info "Migrating to #{migration} (#{migration.version})"
Base.logger.info "Migrating to #{migration.name} (#{migration.version})"
# On our way up, we skip migrating the ones we've already migrated
# On our way down, we skip reverting the ones we've never migrated
@ -470,11 +491,10 @@ module ActiveRecord
raise DuplicateMigrationNameError.new(name.camelize)
end
load(file)
klasses << returning(name.camelize.constantize) do |klass|
class << klass; attr_accessor :version end
klass.version = version
klasses << returning(MigrationProxy.new) do |migration|
migration.name = name.camelize
migration.version = version
migration.filename = file
end
end

View File

@ -922,6 +922,26 @@ if ActiveRecord::Base.connection.supports_migrations?
migrations[0].name == 'innocent_jointable'
end
def test_only_loads_pending_migrations
# migrate up to 1
ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1)
# now unload the migrations that have been defined
PeopleHaveLastNames.unloadable
ActiveSupport::Dependencies.remove_unloadable_constants!
ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", nil)
assert !defined? PeopleHaveLastNames
%w(WeNeedReminders, InnocentJointable).each do |migration|
assert defined? migration
end
ensure
load(MIGRATIONS_ROOT + "/valid/1_people_have_last_names.rb")
end
def test_migrator_interleaved_migrations
ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/interleaved/pass_1")