ActiveRecord Arel OR condition
ActiveRecord queries are ActiveRecord::Relation
objects (which maddeningly do not support or
), not Arel objects (which do).
[ UPDATE: as of Rails 5, "or" is supported in ActiveRecord::Relation
; see https://stackoverflow.com/a/33248299/190135 ]
But luckily, their where
method accepts ARel query objects. So if User < ActiveRecord::Base
...
users = User.arel_tablequery = User.where(users[:kind].eq('admin').or(users[:kind].eq('author')))
query.to_sql
now shows the reassuring:
SELECT "users".* FROM "users" WHERE (("users"."kind" = 'admin' OR "users"."kind" = 'author'))
For clarity, you could extract some temporary partial-query variables:
users = User.arel_tableadmin = users[:kind].eq('admin')author = users[:kind].eq('author')query = User.where(admin.or(author))
And naturally, once you have the query you can use query.all
to execute the actual database call.
I'm a little late to the party, but here's the best suggestion I could come up with:
admins = User.where(:kind => :admin)authors = User.where(:kind => :author)admins = admins.where_values.reduce(:and)authors = authors.where_values.reduce(:and)User.where(admins.or(authors)).to_sql# => "SELECT \"users\".* FROM \"users\" WHERE ((\"users\".\"kind\" = 'admin' OR \"users\".\"kind\" = 'author'))"
As of Rails 5 we have ActiveRecord::Relation#or
, allowing you to do this:
User.where(kind: :author).or(User.where(kind: :admin))
...which gets translated into the sql you'd expect:
>> puts User.where(kind: :author).or(User.where(kind: :admin)).to_sqlSELECT "users".* FROM "users" WHERE ("users"."kind" = 'author' OR "users"."kind" = 'admin')