xhexyq
Last Updated: February 25, 2016
·
1.747K
· oelmekki

`Or` relation in active_record

I've published a gem which allows to easily compute OR queries with active_record.

You can use it this way :

users = User.any_of("email like '%@example.com'", {banned: true}).destroy_all
# => DELETE FROM users WHERE email LIKE '%@example.com' OR banned = '1';

It can be used directly on model class, or through an association, or behind an other relation.

manual_removal = User.where(id: params[:users][:destroy_ids])
User.any_of(manual_removal, "email like '%@example.com'", {banned: true})
@company.users.any_of(manual_removal, "email like '%@example.com'", {banned: true})
User.where(offline: false).any_of( manual_removal, "email like '%@example.com'", {banned: true})

There's also an ongoing pull request on rails core to add this as a core feature : https://github.com/rails/rails/pull/10891

Let us know there if you want this as a rails core feature.

Say Thanks
Respond

7 Responses
Add your response

7249
B0e363feaa6bfc546b75336cf22fc7f4

Yes. Yes, I want this.

over 1 year ago ·
7266
4f873fd56f2bb58c0a13847a46b481f3

Good feature :)
I want it!

over 1 year ago ·
7301
056b8ecb67eade75d571f20a7fb6e5aa

Awesome!

over 1 year ago ·
7307
09170ad180eac32a21b18a536b4a1ae7

Hey take a look to Squeel (https://github.com/ernie/squeel)

SELECT "people".* FROM people
WHERE ("people"."name" LIKE 'Ernie%' AND "people"."salary" < 50000)
OR ("people"."name" LIKE 'Joe%' AND "people"."salary" > 100000)

Person.where{(name =~ 'Ernie%') & (salary < 50000) | (name =~ 'Joe%') & (salary > 100000)}

over 1 year ago ·
7324

@edgarortegaramirez Yes, I know of squeel, I found it while doing preliminary research.

It's a complete solution, but I do not like its syntax that much. There are two different choices, here : squeel implements a whole new query interface while activerecord_any_of tries to stick to AR api.

Also, AFAIK, squeel does not allow to easily compute dynamic OR queries (which is the whole point activerecord_any_of started with), like this :

selected_users = User.where( id: params[user_ids] )
banned_users = User.where( banned: true )
User.any_of( selected_users, banned_users )
over 1 year ago ·
7352

Was looking for just that the other day, nice !

over 1 year ago ·
7370

Love it!

over 1 year ago ·