只需将第三个参数(列的 :type)添加到remove_column
方法使该迁移可逆。所以OP的原始代码实际上确实有效,如下所示:
remove_column :foos, :bar, :boolean
这个答案的其余部分是试图发现为什么这个方法不起作用,但OP最终让它起作用。
我在文档中看到一些相反的信息ActiveRecord::迁移 http://api.rubyonrails.org/classes/ActiveRecord/Migration.html:
一些命令如删除列无法逆转。如果您想定义在这些情况下如何向上和向下移动,则应该像以前一样定义向上和向下方法。
有关可逆命令的列表,请参阅 ActiveRecord::Migration::CommandRecorder。
而这个来自ActiveRecord::迁移::CommandRecorder http://api.rubyonrails.org/classes/ActiveRecord/Migration/CommandRecorder.html:
ActiveRecord::Migration::CommandRecorder 记录迁移期间完成的命令,并知道如何反转这些命令。 CommandRecorder 知道如何反转以下命令:
添加列
添加索引
添加时间戳
创建表
创建连接表
删除时间戳
重命名_列
重命名索引
重命名表
无论如何,这个文档似乎已经过时了......深入研究github上的源码 https://github.com/rails/rails/blob/e1d4673102f7c4e58964a6de864402ae9a615688/activerecord/lib/active_record/migration/command_recorder.rb#L128:
让你悲伤的方法是:
def invert_remove_column(args)
raise ActiveRecord::IrreversibleMigration, "remove_column is only reversible if given a type." if args.size <= 2
super
end
我尝试了一下...在我的 Rails 4.1.2 应用程序上设置了迁移,并且迁移是双向的——向上和向下。这是我的迁移:
class TestRemoveColumn < ActiveRecord::Migration
def change
remove_column :contacts, :test, :boolean
end
end
我也尝试过:boolean
缺少参数并出现与您所说的相同的错误。您确定您使用的是 Rails 4.1.2 的最终版本 - 不是候选版本之一?如果你是,我建议放一个binding.pry
进入 Rails 源代码invert_remove_column
方法来检查参数列表并查看发生了什么。为此,只需运行bundle open activerecord
然后探索:lib/active_record/migration/command_recorder.rb:128.