ActiveRecord Arel OR condition ActiveRecord Arel OR condition ruby ruby

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')