我可以在 Rails 4 及更高版本中使用 change_column 方法回滚吗?

Can I rollback using change_column method in Rails 4 and above?

change_column 方法在 Rails 4 及更高版本中用于迁移时是否能够回滚?

这是一个例子:

def change
  change_column etc
end

我应该改用 updown 方法吗?

编辑:很抱歉花了这么长时间才更新这个答案,我本来没看懂这个问题。

当您在 Rails 中编写迁移时,您可以采用两种方法,您可以使用 changeup down 方法。当您使用 change 时,了解您的迁移正在做什么很重要,因为 change 构造将尝试推断在您必须回滚迁移的情况下相反的操作是什么。 add_columnadd_indexcreate_table 等迁移方法具有相反的作用 rails 可以推断。然而,像 change_column 这样的迁移实际上可以是任何东西,所以就像 Martin 说的那样,您需要为 rails 包含 reversible 块,以便知道在还原可能不明确时该怎么做。

It's possible rollback a migration with change_columns in rails 4 or rails 5 with:

def change end

是的,可以使用空(以及正确的非空)change 方法回滚迁移。

当您确实在那里有一些东西时,如果您没有指定您删除的列的类型,您可能无法使用例如 remove_column 恢复迁移。

此外,如果您在 change 方法中有一个 change_column。如果不是来自 down 方法,Rails 应该如何知道更改前 type/name/whatever 列有哪些? :)

因此,如果您打算来回滚动,您会希望尽可能明确,因此使用 updown 是一个非常好的(实际上是最好的)主意.

change_column 默认情况下无法还原。 Rails无法知道迁移前的列定义,因此无法回滚到这个原始定义。

因此从 Rails 4 开始,您可以向 Rails 提供必要的信息。 这就是 reversible 方法的用途:

def change
  reversible do |dir|
    dir.up do
      change_column :users, :score, :decimal, precision: 6, scale: 2
    end
    dir.down do
      change_column :users, :score, :decimal, precision: 4, scale: 2
    end
  end
end

乍一看,这似乎比使用 updown 更复杂。优点是,您可以将其与可逆迁移混合使用。
例如,如果您将一堆字段添加到 table 并且必须更改几个字段,您可以使用 change_tableadd_column 以及 reversible 以获得干净紧凑的迁移:

def change
  change_table :users do |t|
    t.string :address
    t.date :birthday
    # ...
  end

  reversible do |dir|
    dir.up do
      change_column :users, :score, :decimal, precision: 6, scale: 2
    end
    dir.down do
      change_column :users, :score, :decimal, precision: 4, scale: 2
    end
  end
end

您也可以使用

change_column_null(table_name, column_name, null, default = nil)

保存一些代码。 Activerecord 知道如何回滚这个。