Ruby on rails 如何使remove_列可逆?
我进行了一次迁移,删除了一列:Ruby on rails 如何使remove_列可逆?,ruby-on-rails,rails-migrations,Ruby On Rails,Rails Migrations,我进行了一次迁移,删除了一列: def change remove_column :foos, :bar, :boolean end 当我尝试rake db:rollback该迁移时,我得到以下错误: remove_column is only reversible if given a type. 文档中说,以下是删除\u列的签名: remove_column(table_name, column_name, type, options) 因此,在本例中,我的类型应该是:boolea
def change
remove_column :foos, :bar, :boolean
end
当我尝试rake db:rollback
该迁移时,我得到以下错误:
remove_column is only reversible if given a type.
文档中说,以下是删除\u列的签名:
remove_column(table_name, column_name, type, options)
因此,在本例中,我的类型应该是:boolean
,我希望迁移是可逆的。我错过了什么
为了避免这个问题,我当然可以将其分解为up
和down
迁移,但我想了解change
语法在这种情况下不起作用的原因。不是使用change
,而是使用up
和down
方法进行迁移:
def up
remove_column :foos, :bar
end
def down
add_column :foos, :bar, :boolean
end
class TestRemoveColumn < ActiveRecord::Migration
def change
remove_column :contacts, :test, :boolean
end
end
只需将第三个参数(列的:type)添加到remove\u column
方法中,即可实现可逆迁移。因此OP的原始代码实际上起了作用,如:
remove_column :foos, :bar, :boolean
这个答案的其余部分是试图发现为什么这个方法不起作用,但OP最终让它起了作用
我在文档中看到了一些相反的信息:
某些命令,如删除列无法反转。如果您想定义在这些情况下如何向上和向下移动,那么应该像以前一样定义向上和向下方法
有关可逆命令的列表,请参阅ActiveRecord::Migration::CommandRecorder
这来自:
ActiveRecord::Migration::CommandRecorder记录迁移期间执行的命令,并知道如何反转这些命令。CommandRecorder知道如何反转以下命令:
添加列
添加索引
添加时间戳
创建表
创建连接表
删除时间戳
重命名列
重命名索引
重命名表
无论如何,这个文档似乎已经过时了。。。深入研究:
让你悲伤的方法是:
def invert_remove_column(args)
raise ActiveRecord::IrreversibleMigration, "remove_column is only reversible if given a type." if args.size <= 2
super
end
def invert_remove_列(args)
raise ActiveRecord::不可逆转迁移,“remove_列只有在给定类型时才是可逆的。”如果args.size在本例中使用的是Rails 4.1.2,并且与documentation.def up中列出的版本匹配;删除列:foos,:bar,:boolean;结束;对于迁移和回滚,将调用down。def下降;添加列:foos,:bar,:boolean;结束;我也有这个不可逆转的迁移问题,我已经运行了rake:db-migrate。我不能回滚和编辑,所以我想我只需要用rails销毁迁移名称删除,然后用列类型重做迁移。我会让你知道它会变成什么样子out@tomb啊,我迟到了两年多,我想你提到的步骤一定把你的数据库搞得更糟了):我希望你设法解决了这一切。你不是这样做的。@ARK迟做总比不做好?我确实设法解决了这个问题,并在这里发布了我的步骤:我在Rails代码中的某个地方遇到了一些问题,无法再重现我的问题。我想你可能是对的,我可能使用了一个奇怪的Rails版本(尽管我的文件中有4.1.2)。无论如何,我认为这是一个很好的答案,可以帮助未来的读者在其他人遇到类似问题时解决他们自己的问题。这是一个伟大的研究,试图发现错误的原因。恭喜!这确实有效,但这里有一个巨大的警告:如果要删除包含引用的列(如user\u id
),则该列上可能有一个索引,该索引将由Rails 4+在remove\u column
上自动删除。如果恢复此迁移,即使指定了列类型(如:integer
),也不会在列上重新添加索引,这会给您带来巨大的性能问题。因此,我建议多花一点时间,在迁移过程中编写上下方法。