Migration Command Recorder
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_foreign_key
-
add_check_constraint
-
add_exclusion_constraint
-
add_unique_key
-
add_index
-
add_reference
-
add_timestamps
-
change_column_default (must supply a
:fromand:tooption) -
change_column_null
-
change_column_comment (must supply a
:fromand:tooption) -
change_table_comment (must supply a
:fromand:tooption) -
create_enum
-
create_join_table
-
create_table
-
disable_extension
-
drop_enum (must supply a list of values)
-
drop_join_table
-
drop_table (must supply a block)
-
enable_extension
-
remove_column (must supply a type)
-
remove_columns (must supply a
:typeoption) -
remove_foreign_key (must supply a second table)
-
remove_check_constraint
-
remove_exclusion_constraint
-
remove_unique_key
-
remove_index
-
remove_reference
-
remove_timestamps
-
rename_column
-
rename_index
-
rename_table
- I
- N
- R
Constants
| ReversibleAndIrreversibleMethods | = | [ :create_table, :create_join_table, :rename_table, :add_column, :remove_column, :rename_index, :rename_column, :add_index, :remove_index, :add_timestamps, :remove_timestamps, :change_column_default, :add_reference, :remove_reference, :transaction, :drop_join_table, :drop_table, :execute_block, :enable_extension, :disable_extension, :change_column, :execute, :remove_columns, :change_column_null, :add_foreign_key, :remove_foreign_key, :change_column_comment, :change_table_comment, :add_check_constraint, :remove_check_constraint, :add_exclusion_constraint, :remove_exclusion_constraint, :add_unique_key, :remove_unique_key, :create_enum, :drop_enum, ] |
Attributes
| [RW] | commands | |
| [RW] | delegate | |
| [RW] | reverting |
Class Public methods
new(delegate = nil) Link
Source: show
# File activerecord/lib/active_record/migration/command_recorder.rb, line 61 def initialize(delegate = nil) @commands = [] @delegate = delegate @reverting = false end
Instance Public methods
inverse_of(command, args, &block) Link
Returns the inverse of the given command. For example:
recorder.inverse_of(:rename_table, [:old, :new])
# => [:rename_table, [:new, :old]]
If the inverse of a command requires several commands, returns array of commands.
recorder.inverse_of(:remove_columns, [:some_table, :foo, :bar, type: :string])
# => [[:add_column, :some_table, :foo, :string], [:add_column, :some_table, :bar, :string]]
This method will raise an IrreversibleMigration exception if it cannot invert the command.
Source: show
# File activerecord/lib/active_record/migration/command_recorder.rb, line 108 def inverse_of(command, args, &block) method = :"invert_#{command}" raise IrreversibleMigration, <<~MSG unless respond_to?(method, true) This migration uses #{command}, which is not automatically reversible. To make the migration reversible you can either: 1. Define #up and #down methods in place of the #change method. 2. Use the #reversible method to define reversible behavior. MSG send(method, args, &block) end
record(*command, &block) Link
Record command. command should be a method name and arguments. For example:
recorder.record(:method_name, [:arg1, :arg2])
Source: show
# File activerecord/lib/active_record/migration/command_recorder.rb, line 88 def record(*command, &block) if @reverting @commands << inverse_of(*command, &block) else @commands << (command << block) end end
replay(migration) Link
Source: show
# File activerecord/lib/active_record/migration/command_recorder.rb, line 142 def replay(migration) commands.each do |cmd, args, block| migration.send(cmd, *args, &block) end end
revert() Link
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])
Source: show
# File activerecord/lib/active_record/migration/command_recorder.rb, line 74 def revert @reverting = !@reverting previous = @commands @commands = [] yield ensure @commands = previous.concat(@commands.reverse) @reverting = !@reverting end