Search code examples
ruby-on-railsrubyactiverecordrails-activerecordactive-record-query

Rails Query Active Record By Pairs OR'ed


I have an API that looks like...

get(not_unique_id:, pairs: [])

...where pairs can look like [{ foo: 1, bar: 'a' }, { foo: 2, bar: 'b' }] and I want to write a query that will find all entries for the given non unique id, filtered by the pairs, i.e. ...

Thing.where(not_unique_id: not_unique_id)
# need help here -> .where("(foo = #{pairs.first[:foo]} AND bar = #{pairs.first[:bar]}) OR (foo = #{pairs.second[:foo]} AND bar = #{pairs.second[:bar]}) OR ...")
.map # or whatever else I want to do

I need a way to perform this foo AND bar comparison for each entry in my input pairs, OR'ed together to return all results that are have the not unique ID AND one of the pairs' values.


Solution

  • You can use or to chain together multiple where clauses with ORs:

    Record.where(a: 'b').or(Record.where(c: 'd')).to_sql
    # => select * from records where (a = 'b' OR c = 'd')
    

    Using this and your array of conditions, you can provide a starting "seed" of Record.all to a reduce call and chain multiple successive conditions by oring them onto the scope:

    conditions = [{ foo: 1, bar: 'a' }, { foo: 2, bar: 'b' }]
    
    records = conditions.inject(Record.all) do |scope, condition|
                scope.or(Record.where(condition))
              end