aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNik Wakelin <nik@codetocustomer.com>2008-08-02 17:44:02 +1200
committerMichael Koziarski <michael@koziarski.com>2008-08-06 12:46:52 +0200
commit080974784582e1e289c2948227b446bc56d404a1 (patch)
tree99f7a9679a1dadddfda338db67ef311bafdb902c
parent29a06f10e8600bbda333c30bf294e7896f35b8d5 (diff)
downloadrails-080974784582e1e289c2948227b446bc56d404a1.tar.gz
rails-080974784582e1e289c2948227b446bc56d404a1.tar.bz2
rails-080974784582e1e289c2948227b446bc56d404a1.zip
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]
-rw-r--r--activerecord/lib/active_record/migration.rb32
-rw-r--r--activerecord/test/cases/migration_test.rb20
2 files changed, 46 insertions, 6 deletions
diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb
index 731a350854..fd77f27b77 100644
--- a/activerecord/lib/active_record/migration.rb
+++ b/activerecord/lib/active_record/migration.rb
@@ -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
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index 7ecf755ef8..920f719995 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -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")