【问题标题】:Rails enum without corresponding storage / column没有相应存储/列的 Rails 枚举
【发布时间】:2021-09-28 23:39:38
【问题描述】:

我有以下型号:

class Operation < ApplicationRecord
  enum state: [:started, :restarted, :reloaded, :stopped]
end

但是,Postgres 数据库中的基础表没有state 列。虽然,我可以为 state 属性赋值并保存模型实例,但 state 只是没有保存:

op = Operation.new state: :started
op.save!
=> true

这是我想要的行为,我只想以与 attr_accessor 属性相同的方式使用它,但有一些额外的限制。

问题是,这样使用enum可以吗?或者它是一种未定义的行为,将来可能会更改/修复?

官方文档没有回答这个问题https://api.rubyonrails.org/v6.1.4/classes/ActiveRecord/Enum.html

UPD:是的,正如@ricks 所说,我可以通过以下方式实现相同的目标:

attr_accessor :state
validates :state, inclusion: { in: %i[started reloaded restarted stopped] }, allow_nil: true

enum 的使用对我来说更方便,因为如果值不在允许列表中,它会在分配时引发异常。

【问题讨论】:

  • 您需要哪些附加约束?您只需要将状态作为这 4 个选项之一吗?
  • 是的,我更新了问题。我现在就是这样做的,但是我需要使用有效的?检查状态。所以如果它是安全的,我宁愿使用枚举
  • 我可能会推荐使用attr_accessor,因为它的标准做法是,如果在分配状态时抛出错误而不是对象的另一个可能属于错误类型的属性,这可能会令人困惑,例如将字符串分配给需要为整数的属性。

标签: ruby-on-rails ruby activerecord enums ruby-on-rails-6


【解决方案1】:

您也可以使用attributes api 来执行此操作。

class Operation < ApplicationRecord
  attribute :state
  enum state: [:started, :restarted, :reloaded, :stopped]
end

这将为您提供您正在寻找的所有枚举异常(以及其他枚举方法)。

虽然它不在文档中,但在 rails issue 中建议作为解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多