简体   繁体   English

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

[英]Rails migration add default not null properties to existing boolean field

I have a rails model that has a non-defaulted boolean field that is nullable and am trying to set a default.我有一个 Rails 模型,它有一个可以为空的非默认布尔字段,我正在尝试设置默认值。 I found a blog post about avoiding a 3-stat boolean issue, so am trying to cater for this.我找到了一篇关于避免 3-stat boolean 问题的博客文章,所以我试图满足这一点。 This is the migration I have:这是我的迁移:

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

Running the migration fails because of existing null values in the database.由于数据库中存在空值,运行迁移失败。 What is the correct way to update existing entries to allow the schema change?更新现有条目以允许架构更改的正确方法是什么? Or should the not null control be added to the model:或者应该将非空控件添加到模型中:

validates :is_foo, presence: true

Not sure if adding this to the migration is the "right" way:不确定将其添加到迁移中是否是“正确”的方式:

 Table.update_all(:is_foo => false)

Similarly, this field was added by a migration without extra not null / default parameters.同样,此字段是由迁移添加的,没有额外的非空/默认参数。 Would the migration to add column also require this, or would the default set the value?添加列的迁移是否也需要这个,还是默认设置值? Here's the migration I ran:这是我运行的迁移:

add_column :table, is_foo, :boolean

If I had added ,null: false, default: false on the add_column, would all the values have been set correctly?如果我在 add_column 上添加了,null: false, default: false ,所有值是否都已正确设置?

You could do it this way:你可以这样做:

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

When migrating up it will ensure first that all nulls are converted to false and then change the column to add your restrictions.向上迁移,它将首先确保所有空值都转换为false然后更改列以添加限制。

And yes, you could have avoided this if the first migration contained the restrictions.是的,如果第一次迁移包含限制,您本可以避免这种情况。

I think you are also right adding the model validation.我认为您添加模型验证也是正确的。

You can actually combine the change_column_null and change_column_default methods to accomplish this in a migration.您实际上可以结合change_column_nullchange_column_default方法在迁移中完成此操作。

  1. The change_column_null method lets you add a NOT NUL L constraint, with the last argument specifying what to replace any existing NULL values with. change_column_null方法允许您添加NOT NUL L 约束,最后一个参数指定用什么来替换任何现有的NULL值。

  2. The change_column_default then sets the default for any new records. 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM