Answers:
如果您在迁移中执行此操作,则可能会这样:
# 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
方法不太适合这种情况,因为(1)该update_all
方法将同时在迁移和潜在还原上执行。那可能不是最坏的事情,而是因为(2)迁移无法得知潜在还原中列的更改。因此,在这种情况下,我会坚持使用up
和down
。
在Rails 4中,这是一个更好的(DRYer)解决方案:
change_column_null :my_models, :date_column, false
为确保NULL
在该列中不存在带有值的记录,您可以传递第四个参数,这是用于具有NULL
值的记录的默认值:
change_column_null :my_models, :date_column, false, Time.now
change_column_null
。但是,里克·史密斯(Rick Smith)的上述评论指出了一个非常有效的案例。
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。的第4个值change_column_null
正是这样做的。查看文件更多详细信息,。
另外,我通常更喜欢为该字段设置默认值,这样,每次创建新对象时都不需要指定该字段的值。我也加入了注释掉的代码。
add_column :users, :admin, :string
然后change_column_null(:admin, :string, false, "new_value_for_existing_records")
创建一个change_column
包含带有:default =>
值的语句的迁移。
change_column :my_table, :my_column, :integer, :default => 0, :null => false
请参阅:change_column
根据您可能需要使用的数据库引擎 change_column_null
change_column_null
。
Rails 4:
def change
change_column_null(:users, :admin, false )
end
如果您已有记录,则不能使用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
MyModel.update_all({:date_column => Time.now}, {:date_column => nil})
。以您原始形式进行的查询仅使我所有的模型在该字段中都没有值。