How do you make remove_column reversible?

后端 未结 2 697
旧时难觅i
旧时难觅i 2021-02-03 17:43

I have a migration that removes a column:

def change
  remove_column :foos, :bar, :boolean
end

When I try to rake db:rollback that

相关标签:
2条回答
  • 2021-02-03 17:54

    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
    
    0 讨论(0)
  • 2021-02-03 18:09

    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.

    0 讨论(0)
提交回复
热议问题