rails - 为枚举字段应用默认值

Mar*_*ejo 5 ruby-on-rails

我希望我的枚举字段有一个默认值,以防止它为零.我做了以下事情:

# 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
Run Code Online (Sandbox Code Playgroud)

我在当地环境中获得了预期的结果.但在heroku中并不完全.我需要它draft在更新状态后成为默认值nil,但在此上下文中它变为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]
Run Code Online (Sandbox Code Playgroud)

这是使用枚举的正确用例吗?我错过了我的heroku环境的特殊性吗?

Mar*_*n13 18

轨道 6.1+

从 Rails 6.1 开始,可以在模型中设置默认枚举值。例如:

class Template < ActiveRecord::Base
  enum status: [:draft, :published], _default: :draft
end
Run Code Online (Sandbox Code Playgroud)

这是相对于PR的链接,并在文档的链接


Jef*_*son 15

您可以从数据库声明中设置默认值.

create_table :templates do |t|
  t.column :status, :integer, default: 0
end
Run Code Online (Sandbox Code Playgroud)

然后,将关系映射如下

class Template < ActiveRecord::Base
  enum status: { draft: 0, published: 1 }
end
Run Code Online (Sandbox Code Playgroud)