在Rails 4.1中,如何通过枚举符号查找记录?

Abd*_*ziz 42 ruby ruby-on-rails ruby-on-rails-4 rails-activerecord ruby-on-rails-4.1

假设我有这个模型:

class Conversation < ActiveRecord::Base
  enum status: [ :active, :archived ]
end
Run Code Online (Sandbox Code Playgroud)

如何在不使用枚举的数值或不必迭代每个对话的情况下找到所有活动对话?

我试过了Conversation.where(status: :active),但没有产生任何结果.

想到的唯一解决方案是迭代所有对话并选择活动对话,但它看起来不是一个好的解决方案.

Conversation.all.select {|conversation| conversation.active? }  
Run Code Online (Sandbox Code Playgroud)

我能做些什么吗?

小智 59

ActiveRecord::Enum 根据其值提供范围.

试一试:

Conversation.active
Run Code Online (Sandbox Code Playgroud)

要么

Conversation.archived
Run Code Online (Sandbox Code Playgroud)

当然,您可以像Kyle Decot所提到的那样创建自己的范围.

  • 如果您通过API请求或查询字符串值将该类型值作为字符串传递,则不是真正的解决方案. (2认同)

Mir*_*318 41

这非常有效:

Conversation.where("conversation.status = ?", Conversation.statuses[:active])
Run Code Online (Sandbox Code Playgroud)

由于某种原因,这不起作用:

Conversation.where(status: :active) #searches for NULL
Conversation.where(status: 'active') #searches for status=0 no matter what the enum
Run Code Online (Sandbox Code Playgroud)

更新

以上所有语句都适用于Rails 5.快乐的编码!

  • 请注意,Rails 5将允许所有这些语句工作.呜! (17认同)
  • 答案可以改写为`Conversation.where(status:Conversation.statuses [:active])`.不需要字符串. (3认同)
  • 不幸的是,Rails 5 没有修复通过父级的查询(例如`Person.joins(:conversations).where(conversations: {status: :active})` 错误)。必须使用第一种方法 (`Person.joins(:conversations).where(conversations: {status: Conversation.statuses[:active]})`)。 (2认同)

Kyl*_*cot 27

ActiveRecord :: Enum提供基于值的内置范围,因此您可以简单地执行以下操作:

Conversation.active
Conversation.archived
Run Code Online (Sandbox Code Playgroud)

  • ASAP,enum默认创建这样的范围,所以如果你有`enum status:%i [active archived]`,你已经有了`.active`和`.archived`范围. (2认同)

6ft*_*Dan 8

Conversation.where(status: Conversation.statuses[:active])
Run Code Online (Sandbox Code Playgroud)

  • 无需创建新实例 - "Conversation.statuses [:active]"应该可以正常工作 (3认同)