I have a migration that removes a column:
def change
remove_column :foos, :bar, :boolean
end
When I try to rake db:rollback
that migration, I get the following error:
remove_column is only reversible if given a type.
The ActiveRecord::Migration documentation says that the following is the signature for remove_column
:
remove_column(table_name, column_name, type, options)
So my type in this case should be :boolean
, and I expect that migration to be reversible. What am I missing?
I can certainly break this out into an up
and down
migration to avoid this problem, but I'd like to understand why the change
syntax isn't working in this case.
Simply adding the 3rd argument (the column's :type) to the remove_column
method makes that migration reversible. So the OP's original code actually did work, as in:
remove_column :foos, :bar, :boolean
The rest of this answer was an attempt to discover why this method would not have been working, but the OP ended up getting it to work.
I see somewhat contrary info in the documentation for ActiveRecord::Migration:
Some commands like remove_column cannot be reversed. If you care to define how to move up and down in these cases, you should define the up and down methods as before.
For a list of commands that are reversible, please see ActiveRecord::Migration::CommandRecorder.
And this from 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
Anyway, it appears that this documentation is out of date... Digging into the source on github:
The method that's giving you grief is:
def invert_remove_column(args)
raise ActiveRecord::IrreversibleMigration, "remove_column is only reversible if given a type." if args.size <= 2
super
end
I gave this a shot... setup a migration on my Rails 4.1.2 app and the migration worked both ways -- up and down. Here was my migration:
class TestRemoveColumn < ActiveRecord::Migration
def change
remove_column :contacts, :test, :boolean
end
end
I also tried with the :boolean
argument missing and got the same error as you're talking about. Are you sure you're on the final version of Rails 4.1.2 -- not one of the release candidates? If you are, I'd suggest putting a binding.pry
into the Rails source for the invert_remove_column
method to inspect the arguments list and see what's going on. To do so, just run bundle open activerecord
and then explore to: lib/active_record/migration/command_recorder.rb:128.