我有一个 Rails 模型,它有一个可以为空的非默认布尔字段,我正在尝试设置默认值。我找到了一篇关于避免 3-stat boolean 问题的博客文章,所以我试图满足这一点。这是我的迁移:
def change
change_column :table, is_foo, :boolean, null: false, default: false
end
Run Code Online (Sandbox Code Playgroud)
由于数据库中存在空值,运行迁移失败。更新现有条目以允许架构更改的正确方法是什么?或者应该将非空控件添加到模型中:
validates :is_foo, presence: true
Run Code Online (Sandbox Code Playgroud)
不确定将其添加到迁移中是否是“正确”的方式:
Table.update_all(:is_foo => false)
Run Code Online (Sandbox Code Playgroud)
同样,此字段是由迁移添加的,没有额外的非空/默认参数。添加列的迁移是否也需要这个,还是默认设置值?这是我运行的迁移:
add_column :table, is_foo, :boolean
Run Code Online (Sandbox Code Playgroud)
如果我添加,null: false, default: false了 add_column,是否所有的值都设置正确?
小智 8
您实际上可以结合change_column_null和change_column_default方法来在迁移中完成此操作。
该change_column_null方法允许您添加NOT NUL L 约束,最后一个参数指定要替换任何现有NULL 的内容值。
然后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
Run Code Online (Sandbox Code Playgroud)
你可以这样做:
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
Run Code Online (Sandbox Code Playgroud)
向上迁移时,它将首先确保所有空值都转换为false,然后更改列以添加限制。
是的,如果第一次迁移包含限制,您本可以避免这种情况。
我认为您添加模型验证也是正确的。