Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #10217 from mirasrael/make-migrator-run-transactio…

…nal-4.0

Support transactions in Migrator.run

Conflicts:
	activerecord/CHANGELOG.md
  • Loading branch information...
commit db1594c61c0cd1de53eeaf9e705a609ac8ba95a0 2 parents 77fec13 + 2976558
@rafaelfranca rafaelfranca authored
View
4 activerecord/CHANGELOG.md
@@ -1,5 +1,9 @@
## Rails 4.0.0 (unreleased) ##
+* Run `rake migrate:down` & `rake migrate:up` in transaction if database supports.
+
+ *Alexander Bondarev*
+
* `0x` prefix must be added when assigning hexadecimal string into `bit` column in PostgreSQL.
*kennyj*
View
17 activerecord/lib/active_record/migration.rb
@@ -867,11 +867,18 @@ def current_migration
alias :current :current_migration
def run
- target = migrations.detect { |m| m.version == @target_version }
- raise UnknownMigrationVersionError.new(@target_version) if target.nil?
- unless (up? && migrated.include?(target.version.to_i)) || (down? && !migrated.include?(target.version.to_i))
- target.migrate(@direction)
- record_version_state_after_migrating(target.version)
+ migration = migrations.detect { |m| m.version == @target_version }
+ raise UnknownMigrationVersionError.new(@target_version) if migration.nil?
+ unless (up? && migrated.include?(migration.version.to_i)) || (down? && !migrated.include?(migration.version.to_i))
+ begin
+ ddl_transaction(migration) do
+ migration.migrate(@direction)
+ record_version_state_after_migrating(migration.version)
+ end
+ rescue => e
+ canceled_msg = use_transaction?(migration) ? ", the migration canceled" : ""
+ raise StandardError, "An error has occurred#{canceled_msg}:\n\n#{e}", e.backtrace
+ end
end
end
View
26 activerecord/test/cases/migration_test.rb
@@ -258,6 +258,32 @@ def migrate(x)
"On error, the Migrator should revert schema changes but it did not."
end
+ def test_migrator_one_up_with_exception_and_rollback_using_run
+ unless ActiveRecord::Base.connection.supports_ddl_transactions?
+ skip "not supported on #{ActiveRecord::Base.connection.class}"
+ end
+
+ assert_not Person.column_methods_hash.include?(:last_name)
+
+ migration = Class.new(ActiveRecord::Migration) {
+ def version; 100 end
+ def migrate(x)
+ add_column "people", "last_name", :string
+ raise 'Something broke'
+ end
+ }.new
+
+ migrator = ActiveRecord::Migrator.new(:up, [migration], 100)
+
+ e = assert_raise(StandardError) { migrator.run }
+
+ assert_equal "An error has occurred, the migration canceled:\n\nSomething broke", e.message
+
+ Person.reset_column_information
+ assert_not Person.column_methods_hash.include?(:last_name),
+ "On error, the Migrator should revert schema changes but it did not."
+ end
+
def test_migration_without_transaction
unless ActiveRecord::Base.connection.supports_ddl_transactions?
skip "not supported on #{ActiveRecord::Base.connection.class}"
Please sign in to comment.
Something went wrong with that request. Please try again.