Ruby-on-rails 如何在 Rails 迁移中将可为空的列更改为不可为空?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5966840/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to change a nullable column to not nullable in a Rails migration?
提问by Kevin Pang
I created a date column in a previous migration and set it to be nullable. Now I want to change it to be not nullable. How do I go about doing this assuming there are null rows in that database? I'm ok with setting those columns to Time.now if they're currently null.
我在之前的迁移中创建了一个日期列并将其设置为可以为空。现在我想将其更改为不可为空。假设该数据库中有空行,我该怎么做?如果它们当前为空,我可以将这些列设置为 Time.now。
回答by DanneManne
If you do it in a migration then you could probably do it like this:
如果您在迁移中执行此操作,那么您可能可以这样做:
# 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
回答by mrbrdo
In Rails 4, this is a better (DRYer) solution:
在 Rails 4 中,这是一个更好的 (DRYer) 解决方案:
change_column_null :my_models, :date_column, false
To ensure no records exist with NULLvalues in that column, you can pass a fourth parameter, which is the default value to use for records with NULLvalues:
为确保NULL该列中不存在带值的记录,您可以传递第四个参数,这是用于带NULL值记录的默认值:
change_column_null :my_models, :date_column, false, Time.now
回答by Rick Smith
Rails 4 (other Rails 4 answers have problems):
Rails 4(其他 Rails 4 答案有问题):
def change
change_column_null(:users, :admin, false, <put a default value here> )
# change_column(:users, :admin, :string, :default => "")
end
Changing a column with NULL values in it to not allow NULL will cause problems. This is exactly the type of code that will work fine in your development setup and then crash when you try to deploy it to your LIVEproduction. You should first change NULL values to something valid and thendisallow NULLs. The 4th value in change_column_nulldoes exactly that. See documentationfor more details.
将包含 NULL 值的列更改为不允许 NULL 会导致问题。这正是在您的开发设置中可以正常工作的代码类型,然后当您尝试将其部署到您的LIVE产品时会崩溃。您应该首先将 NULL 值更改为有效的值,然后禁止 NULL 值。中的第四个值change_column_null正是这样做的。有关更多详细信息,请参阅文档。
Also, I generally prefer to set a default value for the field so I won't need to specify the field's value every time I create a new object. I included the commented out code to do that as well.
此外,我通常更喜欢为字段设置默认值,这样每次创建新对象时我都不需要指定字段的值。我也包含了注释掉的代码来做到这一点。
回答by jessecurry
Create a migration that has a change_columnstatement with a :default =>value.
创建一个具有change_column带:default =>值语句的迁移。
change_column :my_table, :my_column, :integer, :default => 0, :null => false
See: change_column
请参阅:change_column
Depending on the database engine you may need to use change_column_null
根据您可能需要使用的数据库引擎 change_column_null
回答by piratebroadcast
Rails 4:
导轨 4:
def change
change_column_null(:users, :admin, false )
end
回答by jmarceli
In Rails 4.02+according to the docsthere is no method like update_allwith 2 arguments. Instead one can use this code:
根据文档,在Rails 4.02+ 中,没有像带有 2 个参数的方法。相反,可以使用以下代码:update_all
# 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
回答by Nicolas Maloeuvre
You can't use add_timestamps and null:false if you have existing records, so here is the solution :
如果您有现有记录,则不能使用 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

