如何在rails中指定和验证枚举?

Kam*_*i81 26 validation activerecord ruby-on-rails

我目前有一个模型Attend将有一个状态列,这个状态列只有几个值.STATUS_OPTIONS = {:yes,:no,:maybe}

1)我不确定在用户插入Attend之前我如何验证这一点?基本上是java中的枚举,但我怎么能在rails中做到这一点?

bar*_*ett 65

现在Rails 4.1包含枚举,您可以执行以下操作:

class Attend < ActiveRecord::Base
    enum size: [:yes, :no, :maybe]
    # also can use the %i() syntax for an array of symbols:
    # %i(yes no maybe)
    validates :size, inclusion: { in: sizes.keys }
end
Run Code Online (Sandbox Code Playgroud)

然后为您提供一个范围(即:Attend.yes,Attend.no,Attend.maybe为每一个检查方法看,如果某些状态设置(即:#yes?,#no?,#maybe?),以及属性setter方法(即:#yes!,#no!,#maybe!).

在枚举上的Rails文档

  • 从我正在阅读的内容来看,当前的枚举实现是针对内部价值而不是因为提出问题而暴露给用户(我认为这是一种耻辱).我从2月14日开始从以下帖子中得到这个.https://github.com/rails/rails/issues/13971 (6认同)
  • 简要说明一下,您必须在验证行之前定义枚举。 (4认同)

mne*_*son 36

创建所需选项的全局可访问数组,然后验证状态列的值:

class Attend < ActiveRecord::Base

  STATUS_OPTIONS = %w(yes no maybe)

  validates :status, :inclusion => {:in => STATUS_OPTIONS}

end
Run Code Online (Sandbox Code Playgroud)

然后,您可以通过访问可能的状态 Attend::STATUS_OPTIONS

  • Pre Rails 4.1这很好.在Rails 4.1+中使用内置的枚举:http://edgeguides.rubyonrails.org/4_1_release_notes.html#active-record-enums (6认同)
  • 在rails 4.1中使用"native"枚举具有在postgresql中使用真正的本机枚举的相同缺点.你需要照顾实际的顺序,你不能轻易修改枚举一旦创建等.而且,使用"本机"rails枚举,这是一个破碎的功能,因为在一边你写和读它们作为蜇,但在另一方面,你需要将它们作为数字查询.至少对于postgresql的枚举,数据库中的所有内容都将显示字符串. (2认同)
  • 使用 `enum` 会使数据库变得不那么可读,你应该参考你的模型来确定这个 `3` 值在数据库中意味着什么。所以,我认为 [this one](http://stackoverflow.com/a/8147002/52499) 是一个更好的答案。毕竟,你不可能一无所获:D (2认同)

小智 11

这是我在Rails 4项目中实现的方式.

class Attend < ActiveRecord::Base
    enum size: [:yes, :no, :maybe]
    validates :size, inclusion: { in: Attend.sizes.keys }
end
Run Code Online (Sandbox Code Playgroud)

Attend.sizes为您提供映射.

Attend.sizes # {"yes" => 0, "no" => 1, "maybe" => 2}
Run Code Online (Sandbox Code Playgroud)

在Rails doc中查看更多内容

  • 与[这一个]基本相同的评论(http://stackoverflow.com/questions/8146965/how-do-i-pecpecify-and-validate-an-enum-in-rails/8147002#comment42094863_26365696),但这赢了不起作用,因为在调用验证之前,枚举属性会在无效值上抛出InvalidArgument异常.更多相关内容:https://github.com/rails/rails/issues/13971 (7认同)

mu *_*ort 5

您可以使用字符串列作为状态,然后使用:inclusion选项validates以确保仅获得期望的结果:

class Attend < ActiveRecord::Base
    validates :size, :inclusion => { :in => %w{yes no maybe} }
    #...
end
Run Code Online (Sandbox Code Playgroud)