【发布时间】:2016-05-08 19:36:34
【问题描述】:
我想为我的枚举字段设置一个默认值,以防止它为 nil。我做了以下事情:
# db/schema.rb
create_table "templates", force: :cascade do |t|
t.integer "status"
end
# app/models/template.rb
class Template < ActiveRecord::Base
STATUSES = [:draft, :published]
enum status: STATUSES
after_initialize :init
def init
self.status ||= STATUSES.index(:draft)
end
end
我在本地环境中得到了预期的结果。但不完全在heroku中。在将状态更新为nil 后,我需要将其设为默认值draft,但在这种情况下,它变为nil,但published 范围仍包含更新后的行。
$ heroku run rails console
> Template.published.pluck :id
=> [1, 2]
> Template.find(1).update(status:nil)
Template Load (4.4ms) SELECT "templates".* FROM "templates" WHERE "templates"."id" = $1 LIMIT 1 [["id", 1]]
Template Load (4.4ms) SELECT "templates".* FROM "templates" WHERE "templates"."id" = $1 LIMIT 1 [["id", 1]]
(1.7ms) BEGIN
(1.7ms) BEGIN
(1.1ms) COMMIT
(1.1ms) COMMIT
=> true
> Template.find(1).status
=> nil
> Template.published.pluck :id
=> [1, 2]
这是使用枚举的正确用例吗?我的 heroku 环境是否有我遗漏的特殊性?
【问题讨论】:
-
您是否考虑过直接从数据库级别执行此操作,通过为迁移中的状态列提供默认整数值(对应于
:draft的值)?类似:t.integer :status, default: 1?你可能不得不做一个change_column相当于那个。 -
@SunnyK 我想到了,但我把它放在模型中因为索引号取决于枚举数组元素的排列,它在模型中。正在考虑这将使将来更容易更改枚举值,因为无需创建迁移来更改默认值的索引。但既然你这么说了,在我看来,更容易同意 0 处的元素是所有情况下的默认值。谢谢!
-
@SunnyK 我把它改成了那个,但我还是有同样的问题。
-
在本地还是在推送到 Heroku 之后?如果在推送到 Heroku 后,请尝试再次手动在 Heroku 上运行迁移
标签: ruby-on-rails enums rails-activerecord