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


当前回答

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个值正是这样做的。有关详细信息,请参阅文档。

此外,我通常更喜欢为字段设置默认值,这样我就不需要每次创建新对象时都指定字段的值。我还包含了注释掉的代码来实现这一点。

其他回答

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个值正是这样做的。有关详细信息,请参阅文档。

此外,我通常更喜欢为字段设置默认值,这样我就不需要每次创建新对象时都指定字段的值。我还包含了注释掉的代码来实现这一点。

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

change_column_null :my_models, :date_column, false

为了确保该列中不存在NULL值的记录,您可以传递第四个参数,这是用于NULL值记录的默认值:

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

在Rails 4.02+中,根据文档,没有像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

创建一个迁移,它有一个change_column语句,值为:default =>。

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

看:change_column

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

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

# 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