class ActiveRecord::Migration::CommandRecorder
ActiveRecord::Migration::CommandRecorder
records commands done
during a migration and knows how to reverse those commands. The CommandRecorder knows how to invert the
following commands:
-
add_column
-
add_index
-
add_timestamps
-
create_table
-
create_join_table
-
remove_timestamps
-
rename_column
-
rename_index
-
rename_table
Attributes
commands[RW]
delegate[RW]
reverting[RW]
Public Class Methods
new(delegate = nil)
click to toggle source
# File lib/active_record/migration/command_recorder.rb, line 21 def initialize(delegate = nil) @commands = [] @delegate = delegate @reverting = false end
Public Instance Methods
inverse_of(command, args, &block)
click to toggle source
Returns the inverse of the given command. For example:
recorder.inverse_of(:rename_table, [:old, :new]) # => [:rename_table, [:new, :old]]
This method will raise an IrreversibleMigration
exception if
it cannot invert the command
.
# File lib/active_record/migration/command_recorder.rb, line 63 def inverse_of(command, args, &block) method = :"invert_#{command}" raise IrreversibleMigration unless respond_to?(method, true) send(method, args, &block) end
record(*command, &block)
click to toggle source
record command
. command
should be a method name
and arguments. For example:
recorder.record(:method_name, [:arg1, :arg2])
# File lib/active_record/migration/command_recorder.rb, line 48 def record(*command, &block) if @reverting @commands << inverse_of(*command, &block) else @commands << (command << block) end end
revert() { || ... }
click to toggle source
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])
# File lib/active_record/migration/command_recorder.rb, line 34 def revert @reverting = !@reverting previous = @commands @commands = [] yield ensure @commands = previous.concat(@commands.reverse) @reverting = !@reverting end
Private Instance Methods
invert_add_foreign_key(args)
click to toggle source
# File lib/active_record/migration/command_recorder.rb, line 172 def invert_add_foreign_key(args) from_table, to_table, add_options = args add_options ||= {} if add_options[:name] options = { name: add_options[:name] } elsif add_options[:column] options = { column: add_options[:column] } else options = to_table end [:remove_foreign_key, [from_table, options]] end
invert_add_index(args)
click to toggle source
# File lib/active_record/migration/command_recorder.rb, line 143 def invert_add_index(args) table, columns, options = *args options ||= {} index_name = options[:name] options_hash = index_name ? { name: index_name } : { column: columns } [:remove_index, [table, options_hash]] end
invert_change_column_null(args)
click to toggle source
# File lib/active_record/migration/command_recorder.rb, line 167 def invert_change_column_null(args) args[2] = !args[2] [:change_column_null, args] end
invert_drop_table(args, &block)
click to toggle source
Calls superclass method
# File lib/active_record/migration/command_recorder.rb, line 119 def invert_drop_table(args, &block) if args.size == 1 && block == nil raise ActiveRecord::IrreversibleMigration, "To avoid mistakes, drop_table is only reversible if given options or a block (can be empty)." end super end
invert_remove_column(args)
click to toggle source
Calls superclass method
# File lib/active_record/migration/command_recorder.rb, line 130 def invert_remove_column(args) raise ActiveRecord::IrreversibleMigration, "remove_column is only reversible if given a type." if args.size <= 2 super end
invert_remove_index(args)
click to toggle source
# File lib/active_record/migration/command_recorder.rb, line 153 def invert_remove_index(args) table, options = *args unless options && options.is_a?(Hash) && options[:column] raise ActiveRecord::IrreversibleMigration, "remove_index is only reversible if given a :column option." end options = options.dup [:add_index, [table, options.delete(:column), options]] end
invert_rename_column(args)
click to toggle source
# File lib/active_record/migration/command_recorder.rb, line 139 def invert_rename_column(args) [:rename_column, [args.first] + args.last(2).reverse] end
invert_rename_index(args)
click to toggle source
# File lib/active_record/migration/command_recorder.rb, line 135 def invert_rename_index(args) [:rename_index, [args.first] + args.last(2).reverse] end
invert_rename_table(args)
click to toggle source
# File lib/active_record/migration/command_recorder.rb, line 126 def invert_rename_table(args) [:rename_table, args.reverse] end
method_missing(method, *args, &block)
click to toggle source
Forwards any missing method call to the target.
Calls superclass method
# File lib/active_record/migration/command_recorder.rb, line 188 def method_missing(method, *args, &block) if @delegate.respond_to?(method) @delegate.send(method, *args, &block) else super end end