Rails 4 and mongoid: programmatically build a query with multiple AND and OR conditions

旧街凉风 提交于 2019-12-11 18:23:00

问题


I want to be able to dynamically transform an input hash like the following:

{ name: ['John', 'Luke'], status: ['ACTIVE', 'SUSPENDED'] }

in a query that will put the different fields (name, status) in a AND relationship, and the values for each field in a OR relationship. In SQL that would be something like this:

SELECT * 
FROM my_class 
WHERE (name LIKE 'John' OR name LIKE 'Luke') 
AND (status LIKE 'ACTIVE' OR status LIKE 'SUSPENDED')

I've tried different approaches but I'm kind of stucked. Here what works for one field with multiple values:

def search(criteria)
    result = MyClass.all

    criteria.each do |field, values|
      values = [values] unless values.respond_to?(:each)

      conditions = []
      values.each do |v|
        conditions << { field => v } unless v.empty?
      end

      result = result.or(conditions) # this is enough for one field only, but how to create an AND condition with the second field (and so on)?
    end

    result
  end

I've read about any_of but it's not completely clear to me how to use it.


回答1:


The query you want to build is:

MyClass.where(
  :name.in   => [ 'John', 'Luke' ],
  :status.in => [ 'ACTIVE', 'SUSPENDED' ]
)

A :field.in works the same as field in (...) in SQL and that's just a short form for an or-statement. That makes things quite a bit easier as you just have to add .in calls to the criteria keys whose vales are arrays, something like this:

query = criteria.each_with_object({}) do |(field, values), query|
  field = field.in if(values.is_a?(Array))
  query[field] = values
end
MyClass.where(query)


来源:https://stackoverflow.com/questions/20861936/rails-4-and-mongoid-programmatically-build-a-query-with-multiple-and-and-or-con

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!