ruby-on-rails rails -为enum字段应用默认值

9rbhqvlz  于 2023-08-08  发布在  Ruby
关注(0)|答案(5)|浏览(170)

我想为枚举字段设置一个默认值,以防止它为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环境有什么特殊之处吗?

kg7wmglp

kg7wmglp1#

Rails 6.1+

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

class Template < ActiveRecord::Base
  enum status: [:draft, :published], _default: :draft
end

字符串
这里是a link to relative PRa link to the docs

Rails 7+

从Rails 7开始,不再需要使用前导下划线。举例来说:

class Template < ActiveRecord::Base
  enum :status, [:draft, :published], default: :draft
end


这里是a link to relative PR和文档的链接。

1hdlvixo

1hdlvixo2#

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

create_table :templates do |t|
  t.column :status, :integer, default: 0
end

字符串
然后,Map关系如下

class Template < ActiveRecord::Base
  enum status: { draft: 0, published: 1 }
end

2ul0zpep

2ul0zpep3#

Rails 7

Rails 6.1允许在模型中设置默认枚举值。
Rails 7引入了定义枚举的新语法。例如:

class Template < ActiveRecord::Base
  enum :status, [:draft, :published], default: :draft
end

字符串
这里有一个link to the relevant PR和一个边缘文档的链接。

olmpazwi

olmpazwi4#

另一种方法是:

class Template < ActiveRecord::Base
  before_create :set_default_status

  enum :status: { draft: 0, published: 1 }

  def set_default_status
    self.status ||= :draft
  end
end

字符串
在这种情况下,你可以保持你的migration文件简单:

...
t.integer :status
...

f4t66c6m

f4t66c6m5#

Rails 7

如果希望枚举字段为字符串而不是整数,请使用下面的方法

class Template < ActiveRecord::Base
   enum :status, { draft: "Draft", published: "Published" }, default: :draft
 end

字符串

相关问题