还原迁移时的ActiveRecord :: IrreversibleMigration异常

Raf*_*aez 3 mysql activerecord ruby-on-rails rails-migrations ruby-on-rails-3

我创建了以下Active Record Migration,它添加和删除了一些索引.

class FixIndexes < ActiveRecord::Migration
  def change
    add_index :table1, :field1, :unique => true

    remove_index :table2, :name => "index_table2_on_field1"
    remove_index :table2, :name => "index_table2_on_field2"

    remove_index :table3, :name => "index_table3_on_field1"
    add_index :table3, [:field1, :field2]
  end
end
Run Code Online (Sandbox Code Playgroud)

当我运行migration($ bundle exec rake db:migrate)时,它按预期正常工作.

不幸的是,当我尝试恢复迁移($ bundle exec rake db:rollback)时,它不起作用并引发ActiveRecord::IrreversibleMigration异常

==  FixIndexes: reverting =====================================================
rake aborted!
An error has occurred, all later migrations canceled:

ActiveRecord::IrreversibleMigration/usr/local/rvm/gems/ruby-1.9.3-p392/gems/activerecord-3.2.14/lib/active_record/migration/command_recorder.rb:42:in `block in inverse'
/usr/local/rvm/gems/ruby-1.9.3-p392/gems/activerecord-3.2.14/lib/active_record/migration/command_recorder.rb:40:in `map'
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  1. 为什么这是不可逆转的迁移?它只是添加和删除一些索引,而不是数据.
  2. 如果我使用def self.updef self.down 不是def change?它会解决问题?
  3. 如何在不从MySQL手动添加和删除索引的情况下立即恢复此更改?

Siv*_*iva 5

在Rails中只有少数命令是可逆的(没有手动命令).他们是

  • add_column

  • add_index

  • add_timestamps

  • CREATE_TABLE

  • create_join_table

  • remove_timestamps

  • rename_column

  • rename_index

  • rename_table

请参考这里

您的迁移包含Rollback remove_index不支持的迁移CommandRecorder.

如果您查看此文档

一些变革是破坏性的,无法逆转.这种迁移应该在它们的down方法中引发 ActiveRecord :: IrreversibleMigration异常.

你的情况就是这样,显然会导致ActiveRecord::IrreversibleMigration异常.

长话短说:如果没有手动命令,remove_index无法撤消.