I have the following migration:
class AddMyColumn < ActiveRecord::Migration[6.1]
def change
add_column :my_table, :my_new_column, :bigint
add_foreign_key :my_table, :my_other_table, column: :my_new_column
add_index :my_table, :my_new_column
end
end
When reversing this migration, I see this error:
Mysql2::Error: Cannot drop index 'index_my_table_on_my_new_column': needed in a foreign key constraint
The Rails guide explicitly says that a change migration using these actions should be reversible.
Re-ordering the add_foreign_key and add_index actions (or in this case, using add_reference) allows the migration to reverse successfully. However, this seems to contradict the documentation that states:
Active Record knows how to reverse a migration's actions automatically... [when using] actions that
changesupports. If you're going to need to use any other methods, you should use reversible or write the up and down methods instead of using the change method
add_column add_foreign_key & add_index are all supported actions.
Does the change method perform any analysis of the actions in order to reverse them appropriately? Or does it simply apply them in the reverse order? Is this behavior documented anywhere?
There is a class that's responsible for reversing known methods:
https://api.rubyonrails.org/classes/ActiveRecord/Migration/CommandRecorder.html#method-i-inverse_of
Migration methods are executed from bottom up inside the
changemethod (which you can just see in the log).https://api.rubyonrails.org/classes/ActiveRecord/Migration/CommandRecorder.html#method-i-revert