首页 文章

如何在Rails迁移中将可空列更改为不可为空?

提问于
浏览
158

我在之前的迁移中创建了一个日期列,并将其设置为可为空 . 现在我想把它改成不可空 . 假设该数据库中有空行,我该怎么做呢?如果它们当前为空,我可以将这些列设置为Time.now .

7 回答

  • 11

    创建具有 change_column 语句且具有 :default => 值的迁移 .

    change_column :my_table, :my_column, :integer, :default => 0, :null => false

    见:change_column

    根据数据库引擎,您可能需要使用 change_column_null

  • 180

    导轨4:

    def change
      change_column_null(:users, :admin, false )
    end
    
  • 127

    Rails 4(其他Rails 4答案有问题):

    def change
      change_column_null(:users, :admin, false, <put a default value here> )
      # change_column(:users, :admin, :string, :default => "")
    end
    

    更改其中包含NULL值的列不允许NULL将导致问题 . 这正是在开发设置中可以正常工作的代码类型,然后在您尝试将其部署到LIVE 生产环境 时崩溃 . 您应该首先将NULL值更改为有效的值,然后禁止NULL . change_column_null 中的第4个值就是这样 . 有关详细信息,请参阅documentation .

    另外,我通常更喜欢为字段设置默认值,因此每次创建新对象时都不需要指定字段的值 . 我还包括注释掉的代码 .

  • 3

    如果你在迁移中执行它,那么你可能会这样做:

    # Make sure no null value exist
    MyModel.where(date_column: nil).update_all(date_column: Time.now)
    
    # Change the column to not allow null
    change_column :my_models, :date_column, :datetime, null: false
    
  • 27

    在Rails 4中,这是一个更好的(DRYer)解决方案:

    change_column_null :my_models, :date_column, false
    

    要确保该列中没有 NULL 值的记录,您可以传递第四个参数,该参数是用于具有 NULL 值的记录的默认值:

    change_column_null :my_models, :date_column, false, Time.now
    
  • 1

    Rails 4.02+ 中,根据docs,没有像 update_all 这样的方法有2个参数 . 相反,可以使用此代码:

    # Make sure no null value exist
    MyModel.where(date_column: nil).update_all(date_column: Time.now)
    
    # Change the column to not allow null
    change_column :my_models, :date_column, :datetime, null: false
    
  • 60

    如果您有现有记录,则不能使用add_timestamps和null:false,因此这里是解决方案:

    def change
      add_timestamps(:buttons, null: true)
    
      Button.find_each { |b| b.update(created_at: Time.zone.now, updated_at: Time.zone.now) }
    
      change_column_null(:buttons, :created_at, false)
      change_column_null(:buttons, :updated_at, false)
    end
    

相关问题