你如何使 remove_column 可逆? [英] How do you make remove_column reversible?

查看:61
本文介绍了你如何使 remove_column 可逆?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个删除列的迁移:

I have a migration that removes a column:

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

当我尝试 rake db:rollback 那个迁移时,我收到以下错误:

When I try to rake db:rollback that migration, I get the following error:

remove_column is only reversible if given a type.

ActiveRecord::Migration 文档说以下是 remove_column<的签名/代码>:

The ActiveRecord::Migration documentation says that the following is the signature for remove_column:

remove_column(table_name, column_name, type, options)

所以在这种情况下我的类型应该是 :boolean,并且我希望迁移是可逆的.我错过了什么?

So my type in this case should be :boolean, and I expect that migration to be reversible. What am I missing?

我当然可以将其分解为 updown 迁移以避免此问题,但我想了解为什么 change 语法在这种情况下不起作用.

I can certainly break this out into an up and down migration to avoid this problem, but I'd like to understand why the change syntax isn't working in this case.

推荐答案

只需将第 3 个参数(列的 :type)添加到 remove_column 方法即可使迁移可逆.所以 OP 的原始代码确实有效,如:

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

这个答案的其余部分是试图发现为什么这种方法不起作用,但 OP 最终让它起作用.

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.

我在 ActiveRecord::Migration 的文档中看到了一些相反的信息:

I see somewhat contrary info in the documentation for ActiveRecord::Migration:

某些命令(例如 remove_column)无法撤消.如果你想定义在这些情况下如何上下移动,你应该像以前一样定义 up 和 down 方法.

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.

有关可逆命令的列表,请参阅 ActiveRecord::Migration::CommandRecorder.

For a list of commands that are reversible, please see ActiveRecord::Migration::CommandRecorder.

这来自 ActiveRecord::Migration::CommandRecorder:

ActiveRecord::Migration::CommandRecorder 记录迁移期间执行的命令,并知道如何反转这些命令.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

add_timestamps

创建表

create_join_table

create_join_table

remove_timestamps

remove_timestamps

rename_column

rename_column

rename_index

rename_index

rename_table

rename_table

无论如何,这个文档似乎已经过时了......深入研究 github 上的源码:

Anyway, it appears that this documentation is out of date... Digging into 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 应用程序上设置了一个迁移,迁移是双向的——向上和向下.这是我的迁移:


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

我也尝试过使用 :boolean 参数丢失并得到与您所说的相同的错误.您确定您使用的是 Rails 4.1.2 的最终版本——不是候选版本之一吗?如果您是,我建议将 binding.pry 放入 invert_remove_column 方法的 Rails 源代码中,以检查参数列表并查看发生了什么.为此,只需运行 bundle open activerecord,然后浏览到:lib/active_record/migration/command_recorder.rb:128.

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.

这篇关于你如何使 remove_column 可逆?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆