Rails迁移:向现有的布尔字段添加默认非空属性

6

我有一个Rails模型,其中有一个非默认布尔字段,该字段可为空,并且正在尝试设置默认值。我发现了一篇关于避免3状态布尔问题的博客文章,因此正在尝试适应这一点。这是我拥有的迁移:

def change
  change_column :table, is_foo, :boolean, null: false, default: false
end

由于数据库中存在空值,运行迁移失败。更新现有条目以允许模式更改的正确方法是什么?或者应该将非空控件添加到模型中:

validates :is_foo, presence: true

不确定将此添加到迁移中是否是“正确”的方法:

 Table.update_all(:is_foo => false)

同样地,这个字段是由一个迁移添加的,没有额外的非空/默认参数。那么添加列的迁移是否也需要这个呢,还是默认设置了值?以下是我运行的迁移:

add_column :table, is_foo, :boolean

如果我在add_column上添加了null: false, default: false,所有的值都会被正确设置吗?
2个回答

8

在迁移中,您可以结合使用change_column_nullchange_column_default方法来完成此操作。

  1. change_column_null方法允许您添加一个NOT NULL约束条件,其中最后一个参数指定要用什么替换任何现有的NULL值。

  2. change_column_default方法设置任何新记录的默认值。

class UpdateTable < ActiveRecord::Migration
  def change
    change_column_null :table, :is_foo, false, false
    change_column_default :table, :is_foo, false
  end
end

6
你可以这样做:
class UpdateFoo < ActiveRecord::Migration
  def change
    reversible do |direction|
      direction.up {
        Table.where(is_foo: nil).update_all(is_foo: false)
      }
    end
    change_column :table, :is_foo, :boolean, null: false, default: false
  end
end

当进行向上迁移时,它会首先确保所有的nulls被转换为 false,然后再更改列以添加你的限制条件。

如果第一次迁移包含了这些限制条件,那么你就可以避免这种情况。

我认为你加入模型验证也是正确的。


在这行代码中,is_foe之前缺少一个冒号:change_column :table, is_foo, :boolean, null: false, default: false应该改为 change_column :table, :is_foo, :boolean, null: false, default: false - Richi González
谢谢,@RichiGonzález。完成了。 - chipairon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接