From 65e154f33b54acf40b51082fc5b681ba605015d9 Mon Sep 17 00:00:00 2001 From: Marc-Andre Lafortune Date: Mon, 6 Aug 2012 22:25:01 -0400 Subject: Allow revert of whole migration [#8267] --- activerecord/lib/active_record/migration.rb | 42 ++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb index 14c1fb9ae2..c605c2da7f 100644 --- a/activerecord/lib/active_record/migration.rb +++ b/activerecord/lib/active_record/migration.rb @@ -379,7 +379,8 @@ module ActiveRecord self.verbose = true self.delegate = new - # Reverses the migration commands for the given block. + # Reverses the migration commands for the given block and + # the given migrations. # # The following migration will remove the table 'horses' # and create the table 'apples' on the way up, and the reverse @@ -399,9 +400,25 @@ module ActiveRecord # end # end # - # This command can be nested. + # Or equivalently, if +TenderloveMigration+ is defined as in the + # documentation for Migration: + # + # require_relative '2012121212_tenderlove_migration' + # + # class FixupTLMigration < ActiveRecord::Migration + # def change + # revert TenderloveMigration + # + # create_table(:apples) do |t| + # t.string :variety + # end + # end + # end # - def revert + # This command can be nested. + def revert(*migration_classes) + run(*migration_classes.reverse, revert: true) unless migration_classes.empty? + if block_given? if @connection.respond_to? :revert @connection.revert { yield } else @@ -415,12 +432,31 @@ module ActiveRecord send(cmd, *args, &block) end end + end end def reverting? @connection.respond_to?(:reverting) && @connection.reverting end + # Runs the given migration classes. + # Last argument can specify options: + # - :direction (default is :up) + # - :revert (default is false) + def run(*migration_classes) + opts = migration_classes.extract_options! + dir = opts[:direction] || :up + dir = (dir == :down ? :up : :down) if opts[:revert] + if reverting? + # If in revert and going :up, say, we want to execute :down without reverting, so + revert { run(*migration_classes, direction: dir, revert: true) } + else + migration_classes.each do |migration_class| + migration_class.new.exec_migration(@connection, dir) + end + end + end + def up self.class.delegate = self return unless self.class.respond_to?(:up) -- cgit v1.2.3