But in Rails 5.1.4's current state this get's too complicated to accomplish with the Arel or-chain.
But I still wanted to use Rails to generate as much of the query as possible.
So I made a small hack:
In my model I created a private method called sql_where:
private
def self.sql_where(*args)
sql = self.unscoped.where(*args).to_sql
match = sql.match(/WHERE\s(.*)$/)
"(#{match[1]})"
end
Next in my scope I created an array to hold the OR's
scope :whatever, -> {
ors = []
ors << sql_where(A, B)
ors << sql_where(C, D)
ors << sql_where(E, F)
# Now just combine the stumps:
where(ors.join(' OR '))
}
Which will produce the expected query result:
SELECT * FROM `models` WHERE ((A AND B) OR (C AND D) OR (E AND F)).
And now I can easily combine this with other scopes etc. without any wrongful OR's.
The beauty being that my sql_where takes normal where-clause arguments:
sql_where(name: 'John', role: 'admin') will generate (name = 'John' AND role = 'admin').