Question

Given the SQL conditions cond1, cond2 and cond3 generated using Arel operators (.eq for example), I cannot seem to use Arel to produce the SQL:

SELECT * FROM <table> WHERE (cond1 AND cond2) OR cond3

This is because to AND conditions together you use .where(), but you can't then .or() the result of .where(). You can only .or() conditions together inside a .where(). I.e. .where and .or are not on the same "level", I would guess one needs a dedicated .and() method on the same level as .or().

Note that the brackets around (cond1 AND cond2) denotes that these conditions are ANDed together at the same time, where the OR cond3 is added in another iteration of the loop. They make no difference to the result of the query.

I've read the Arel README and there is no example for this situation and I can't figure out how to dynamically build up this query (in a loop) using Squeel, which has an OR operator |.

Was it helpful?

Solution

Arel::Nodes::Grouping wraps nodes in parentheses.

Arel::Nodes::Grouping.new(Arel::Nodes::And.new("blah", "there")).to_sql
# => ('blah' AND 'there')

OTHER TIPS

Using Rails 5.2 (should work with Rails 5+ or perhaps even earlier)

and_conds = Table.arel_table.grouping(
  Table.where(a: 'test', b: 2).arel.constraints.reduce(:and)
)
Table.where(and_conds).or(Table.where(a: 'blah'))

Results in something similar to...

select * from table where ((a = 'test' and b = 2) or a = 'blah')

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top