我有一个删除列的迁移:
def change
remove_column :foos, :bar, :boolean
end
当我尝试rake db:rollback
迁移时,我收到以下错误:
remove_column is only reversible if given a type.
ActiveRecord::Migration文档说明以下是remove_column
的签名:
remove_column(table_name, column_name, type, options)
所以我在这种情况下的类型应该是:boolean
,我希望迁移是可逆的。我错过了什么?
我当然可以将其分解为up
和down
迁移以避免此问题,但我想了解为什么change
语法不是{\ n}在这种情况下工作。
答案 0 :(得分:71)
只需将第三个参数(列的类型)添加到remove_column
方法,即可使迁移成为可逆。所以OP的原始代码确实有效,如:
remove_column :foos, :bar, :boolean
这个答案的其余部分是试图发现为什么这种方法不起作用,但OP最终让它发挥作用。
我在ActiveRecord::Migration的文档中看到了一些相反的信息:
remove_column 等命令无法撤消。如果你想在这些情况下定义如何上下移动,你应该像以前一样定义上下方法。
有关可逆的命令列表,请参阅ActiveRecord :: Migration :: CommandRecorder。
这来自ActiveRecord::Migration::CommandRecorder:
ActiveRecord :: Migration :: CommandRecorder记录迁移期间完成的命令,并知道如何反转这些命令。 CommandRecorder知道如何反转以下命令:
add_column
add_index
add_timestamps
CREATE_TABLE
create_join_table
remove_timestamps
rename_column
rename_index
rename_table
无论如何,这个文档似乎已经过时了......挖掘the source on github:
给你悲伤的方法是:
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 。
答案 1 :(得分:1)
您可以使用change
和up
方法迁移,而不是使用down
:
def up
remove_column :foos, :bar
end
def down
add_column :foos, :bar, :boolean
end