Rails迁移将默认非空属性添加到现有布尔字段

时间:2016-07-06 06:03:39

标签: ruby-on-rails

我有一个rails模型,它有一个可以为空的非默认布尔字段,我试图设置一个默认值。我发现了一篇关于避免3-stat布尔问题的博客文章,所以我试图迎合这个问题。这是我的迁移:

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

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

validates :is_foo, presence: true

不确定是否以“正确”的方式将其添加到迁移中:

 Table.update_all(:is_foo => false)

同样,此字段是通过迁移添加的,没有额外的非null / default参数。迁移到添加列是否也需要这个,或者默认设置值?这是我运行的迁移:

add_column :table, is_foo, :boolean

如果我在add_column上添加了,null: false, default: false,是否所有值都已正确设置?

2 个答案:

答案 0 :(得分:2)

你可以这样做:

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 然后更改列添加你的限制。

是的,如果第一次迁移包含限制,你可以避免这种情况。

我认为您也正确添加模型验证。

答案 1 :(得分:1)

您实际上可以合并change_column_nullchange_column_default方法,以便在迁移中实现此目的。

  1. change_column_null方法允许您添加 NOT NUL L约束,最后一个参数指定要替换任何现有 NULL 值的内容。

  2. change_column_default然后设置任何新记录的默认值。

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