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

时间:2015-02-02 05:27:57

标签: ruby-on-rails-4

mymodel.rb

enum status: { posted: 1, failed: 2, suspended: 3 }

mycontroller.rb

def filter_params
  params.fetch(:mymodel, {}).
  permit(
    :status => []
    )
end

我有像mymodel[:status] => ["failed", "suspended"]

这样的参数

如何按状态获取所有结果为failedsuspended

类似于:Mymodel.where(status: filter_params[:status])

非常感谢!

来电时:

@mymodel = Mymodel.new(filter_params)

我收到了这个错误:

'["failed", "suspended"]' is not a valid status

2 个答案:

答案 0 :(得分:9)

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

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

values = Mymodel.statuses.values_at(*Array(filter_params[:status]))

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

Mymodel.where(status: values)

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

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

请注意,return all if values.blank?行可以在不中断查询的情况下输入nil或空数组。

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

Mymodel.for_statuses(filter_params[:status])

请注意,您无法创建具有多种状态的记录。 enum仅限制可分配的值,但您只能分配一个,否则会出现not a valid status错误。

有关enum

的详情,请参阅the Rails documentation

答案 1 :(得分:4)

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

Mymodel.where(status: ['failed', 'suspended'])

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

statuses = filter_params[:status].map(&:to_sym)
Mymodel.where(status: statuses)