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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 01:06:33  来源:igfitidea点击:

How to change a nullable column to not nullable in a Rails migration?

ruby-on-railsmigration

提问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