diff options
author | Marc-Andre Lafortune <github@marc-andre.ca> | 2012-08-06 20:44:05 -0400 |
---|---|---|
committer | Marc-Andre Lafortune <github@marc-andre.ca> | 2012-12-21 13:54:51 -0500 |
commit | d327c1805a58641a15d76e5e7de2f3fa1c0b9d03 (patch) | |
tree | 0b486628402e22288afa775ee92b15cf6c68fdfa /activerecord/lib/active_record/migration | |
parent | 740dbf8d42f6bef86845086690ac522cf91ceece (diff) | |
download | rails-d327c1805a58641a15d76e5e7de2f3fa1c0b9d03.tar.gz rails-d327c1805a58641a15d76e5e7de2f3fa1c0b9d03.tar.bz2 rails-d327c1805a58641a15d76e5e7de2f3fa1c0b9d03.zip |
Allow reverting of migration commands with Migration#revert [#8267]
Diffstat (limited to 'activerecord/lib/active_record/migration')
-rw-r--r-- | activerecord/lib/active_record/migration/command_recorder.rb | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/activerecord/lib/active_record/migration/command_recorder.rb b/activerecord/lib/active_record/migration/command_recorder.rb index 55c384ae41..a79428b69a 100644 --- a/activerecord/lib/active_record/migration/command_recorder.rb +++ b/activerecord/lib/active_record/migration/command_recorder.rb @@ -16,35 +16,54 @@ module ActiveRecord class CommandRecorder include JoinTable - attr_accessor :commands, :delegate + attr_accessor :commands, :delegate, :reverting def initialize(delegate = nil) @commands = [] @delegate = delegate + @reverting = false + end + + # While executing the given block, the recorded will be in reverting mode. + # All commands recorded will end up being recorded reverted + # and in reverse order. + # For example: + # + # recorder.revert{ recorder.record(:rename_table, [:old, :new]) } + # # same effect as recorder.record(:rename_table, [:new, :old]) + def revert + @reverting = !@reverting + previous = @commands + @commands = [] + yield + ensure + @commands = previous.concat(@commands.reverse) + @reverting = !@reverting end # record +command+. +command+ should be a method name and arguments. # For example: # # recorder.record(:method_name, [:arg1, :arg2]) - def record(*command) - @commands << command + def record(*command, &block) + if @reverting + @commands << inverse_of(*command, &block) + else + @commands << (command << block) + end end - # Returns a list that represents commands that are the inverse of the - # commands stored in +commands+. For example: + # Returns the inverse of the given command. For example: # - # recorder.record(:rename_table, [:old, :new]) - # recorder.inverse # => [:rename_table, [:new, :old]] + # recorder.inverse_of(:rename_table, [:old, :new]) + # # => [:rename_table, [:new, :old]] # # This method will raise an +IrreversibleMigration+ exception if it cannot - # invert the +commands+. - def inverse - @commands.reverse.map { |name, args| - method = :"invert_#{name}" - raise IrreversibleMigration unless respond_to?(method, true) - send(method, args) - } + # invert the +command+. + def inverse_of(command, args, &block) + method = :"invert_#{command}" + raise IrreversibleMigration unless respond_to?(method, true) + send(method, args, &block) end def respond_to?(*args) # :nodoc: @@ -56,9 +75,9 @@ module ActiveRecord :change_column, :change_column_default, :add_reference, :remove_reference, ].each do |method| class_eval <<-EOV, __FILE__, __LINE__ + 1 - def #{method}(*args) # def create_table(*args) - record(:"#{method}", args) # record(:create_table, args) - end # end + def #{method}(*args, &block) # def create_table(*args, &block) + record(:"#{method}", args, &block) # record(:create_table, args, &block) + end # end EOV end alias :add_belongs_to :add_reference |