Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you make remove_column reversible?

People also ask

Is remove_ column reversible?

As of Rails 4.0, remove_column can now be reversed, with just a little bit more effort. You can pass in the column's type and options (default, limit, etc.)

What is reversible migration in Rails?

Reversible Migrations Rails allows us to rollback changes to the database with the following command. rails db:rollback. This command reverts the last migration that was run on the database. If the migration added a column event_type then the rollback will remove that column.

What is irreversible migration?

The migration that cannot be undone: Irreversible Migration.

How do you delete a column in Rails?

The change method can be used to drop a column in Rails 4 applications, but should not be used in Rails 3. I updated my answer accordingly. You can also use remove_column :table_name, :column_name, :type, :options within the change method, since if you specify the type reverting the migration is possible.


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.


Instead of using change, you use up and down methods to your migration:

def up
  remove_column :foos, :bar
end

def down
  add_column :foos, :bar, :boolean
end