Permalink
Browse files

refactor the migrate method to filter migrations before running them

  • Loading branch information...
1 parent 0f743bc commit 280e4cba13e3aa332496280d3d74b00fdbaeeced @tenderlove tenderlove committed Jan 13, 2012
Showing with 33 additions and 26 deletions.
  1. +32 −25 activerecord/lib/active_record/migration.rb
  2. +1 −1 activerecord/test/cases/migration_test.rb
@@ -682,51 +682,38 @@ def run
end
def migrate(&block)
- current = migrations.detect { |m| m.version == current_version }
- target = migrations.detect { |m| m.version == @target_version }
-
- if target.nil? && @target_version && @target_version > 0
+ if !target && @target_version && @target_version > 0
raise UnknownMigrationVersionError.new(@target_version)
end
- start = up? ? 0 : (migrations.index(current) || 0)
- finish = migrations.index(target) || migrations.size - 1
- runnable = migrations[start..finish]
-
- # skip the last migration if we're headed down, but not ALL the way down
- runnable.pop if down? && target
-
- ran = []
runnable.each do |migration|
if block && !block.call(migration)
next
end
Base.logger.info "Migrating to #{migration.name} (#{migration.version})" if Base.logger
- seen = migrated.include?(migration.version.to_i)
-
- # On our way up, we skip migrating the ones we've already migrated
- next if up? && seen
-
- # On our way down, we skip reverting the ones we've never migrated
- if down? && !seen
- migration.announce 'never migrated, skipping'; migration.write
- next
- end
-
begin
ddl_transaction do
migration.migrate(@direction)
record_version_state_after_migrating(migration.version)
end
- ran << migration
rescue => e
canceled_msg = Base.connection.supports_ddl_transactions? ? "this and " : ""
raise StandardError, "An error has occurred, #{canceled_msg}all later migrations canceled:\n\n#{e}", e.backtrace
end
end
- ran
+ end
+
+ def runnable
+ runnable = migrations[start..finish]
+ if up?
+ runnable.reject { |m| ran?(m) }
+ else
+ # skip the last migration if we're headed down, but not ALL the way down
+ runnable.pop if target
+ runnable.find_all { |m| ran?(m) }
+ end
end
def migrations
@@ -743,6 +730,26 @@ def migrated
end
private
+ def ran?(migration)
+ migrated.include?(migration.version.to_i)
+ end
+
+ def current
+ migrations.detect { |m| m.version == current_version }
+ end
+
+ def target
+ migrations.detect { |m| m.version == @target_version }
+ end
+
+ def finish
+ migrations.index(target) || migrations.size - 1
+ end
+
+ def start
+ up? ? 0 : (migrations.index(current) || 0)
+ end
+
def validate(migrations)
name ,= migrations.group_by(&:name).find { |_,v| v.length > 1 }
raise DuplicateMigrationNameError.new(name) if name
@@ -312,7 +312,7 @@ def migrate(x); raise 'Something broke'; end
def test_only_loads_pending_migrations
# migrate up to 1
- ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1)
+ ActiveRecord::SchemaMigration.create!(:version => '1')
proxies = ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", nil)

0 comments on commit 280e4cb

Please sign in to comment.