Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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]
  • Loading branch information...
commit 080974784582e1e289c2948227b446bc56d404a1 1 parent 29a06f1
@nikz nikz authored NZKoz committed
View
32 activerecord/lib/active_record/migration.rb
@@ -349,6 +349,27 @@ def method_missing(method, *arguments, &block)
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 @@ def migrate
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 @@ def migrations
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
20 activerecord/test/cases/migration_test.rb
@@ -922,6 +922,26 @@ def test_finds_pending_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")
Please sign in to comment.
Something went wrong with that request. Please try again.