如何在ActiveRecord中查询枚举字段的多个值?

Hie*_* Le 7 ruby-on-rails-4

mymodel.rb

enum status: { posted: 1, failed: 2, suspended: 3 }
Run Code Online (Sandbox Code Playgroud)

mycontroller.rb

def filter_params
  params.fetch(:mymodel, {}).
  permit(
    :status => []
    )
end
Run Code Online (Sandbox Code Playgroud)

我有类似的参数 mymodel[:status] => ["failed", "suspended"]

如何通过状态获得所有结果是failedsuspended

就像是: Mymodel.where(status: filter_params[:status])

非常感谢!

当一个电话:

@mymodel = Mymodel.new(filter_params)
Run Code Online (Sandbox Code Playgroud)

我收到了这个错误:

'["failed", "suspended"]' is not a valid status
Run Code Online (Sandbox Code Playgroud)

fiv*_*git 10

运行查询时,需要提供enum属性的序数值.因此,您需要使用其整数值进行查询,而不是像'failed'或的字符串'suspended'.

幸运的是,您可以访问哈希以轻松地将所有状态映射到filter_params哈希中的整数:

values = Mymodel.statuses.values_at(*Array(filter_params[:status]))
Run Code Online (Sandbox Code Playgroud)

有了它,您可以运行查询以获取具有任何已过滤状态的所有记录:

Mymodel.where(status: values)
Run Code Online (Sandbox Code Playgroud)

您不希望在整个地方分散这段代码,因此我建议您将其作为模型中的范围实现:

class Mymodel < ActiveRecord::Base
  enum status: { posted: 1, failed: 2, suspended: 3 }

  scope :for_statuses, ->(values) do
    return all if values.blank?

    where(status: statuses.values_at(*Array(values)))
  end
end
Run Code Online (Sandbox Code Playgroud)

请注意,该return all if values.blank?行可以在nil不破坏查询的情况下抛出或插入空数组.

您现在可以轻松查询记录:

Mymodel.for_statuses(filter_params[:status])
Run Code Online (Sandbox Code Playgroud)

请注意,您无法创建具有多个状态的记录.enum仅限制可以分配的值,但您只能分配一个,否则您将收到not a valid status错误.

有关更多信息,请参阅Rails文档enum.


ero*_*sko 7

Rails 5中,您现在可以将字符串数组传递给查询,例如:

Mymodel.where(status: ['failed', 'suspended'])
Run Code Online (Sandbox Code Playgroud)

对于早期版本,只需将数组值转换为符号:

statuses = filter_params[:status].map(&:to_sym)
Mymodel.where(status: statuses)
Run Code Online (Sandbox Code Playgroud)