Meltemi
Meltemi

Reputation: 38359

Rails - chain 'where' scopes with OR

I can chain scopes like so:

scoped = User.where(sex: 'F')
scoped = scoped.where(color: 'blue')

ActiveRecord generates this SQL for the 1st line:

SELECT COUNT(*) FROM "users"  WHERE "users"."sex" = 'F'

And this SQL for the 2nd line:

SELECT COUNT(*) FROM "users"  WHERE "users"."sex" = 'F' AND "users"."color" = 'blue'

While keeping the initial query so it's built over 2 lines how can I change it from AND to OR so the end result looks like:

SELECT COUNT(*) FROM "users"  WHERE "users"."sex" = 'F' OR "users"."color" = 'blue'

Upvotes: 0

Views: 2606

Answers (2)

jeffdill2
jeffdill2

Reputation: 4114

If you use the squeel gem, you can implement this like so:

User.where(
  { sex: 'F' } |
  { color: 'blue' }
)

However, since it sounds like you need to build the query dynamically, I'd recommend doing something like this:

queries = [
  "sex = 'F'",
  "color = 'blue'"
]

User.where(queries.join(" OR "))

With this method, you can dynamically add as many queries as you need to the queries array. Obviously, you'll have to write the queries in raw SQL but this is the only option I'm aware of for accomplishing this with ActiveRecord.

UPDATE

To answer @Thomas question in the comments:

I'm wondering if there is a way to utilize join data with this. Like user.sex instead of sex.

queries = [
  "users.sex = 'F'",
  "color = 'blue'"
]

Car.joins(:user).where(queries.join(" OR "))

Upvotes: 0

Logan Serman
Logan Serman

Reputation: 29870

Without extensions, this is currently impossible with Rails unless you use raw SQL:

User.where('sex = ? OR color = ?', 'F', 'blue')

In Rails 5, these types of ORs will be supported out of the box.

Upvotes: 2

Related Questions