# Chain scopes with OR

**URL:** <https://www.ruby-forum.com/t/chain-scopes-with-or/219860>\
**Category:** Rails\
**Created:** [May 18, 2012, 7:24pm UTC](https://www.ruby-forum.com/t/chain-scopes-with-or/219860 "2012-05-18T19:24:39Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![dubstep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/cdc98d/32.png) [@dubstep](https://www.ruby-forum.com/u/dubstep)\
**Post date:** [May 18, 2012, 7:24pm UTC](https://www.ruby-forum.com/t/chain-scopes-with-or/219860/1 "2012-05-18T19:24:39Z")

</div>

Hi all!

I’ve googled all over and I couldn’t find anything about chaining scopes  
with OR instead of the default AND.

I have an Asset model with the following scopes:

class Asset \< ActiveRecord::Base

(…)

scope :find\_in\_coverage, lambda { where(‘timestamp(assets.found\_at) \>=  
?’, Asset.found\_at\_limit) }  
scope :find\_unknown\_in\_coverage, where(‘assets.asset\_type\_id IS  
NULL’).find\_in\_coverage  
scope :find\_known\_missing, lambda { where(‘assets.found\_at \< ? AND  
assets.asset\_type\_id IS NOT NULL’, Asset.found\_at\_limit) }

end

I would like to create another scope (“find\_visibles”) which is the OR  
of  
“find\_in\_coverage” and “find\_known\_missing” scopes, like that:

scope :find\_visibles, find\_in\_coverage.find\_know\_missing

The problem is that this method chain uses AND to concatenate WHERE  
clauses. I need this clauses to be concatenated using OR instead.

How can I do that?

Thanks in advance,  
Gustavo Honorato

---

<div class="post-metadata">

**Author:** ![SSGustavo\_de\_SSS\_Ca](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/cab0a1/32.png) [@SSGustavo\_de\_SSS\_Ca](https://www.ruby-forum.com/u/SSGustavo_de_SSS_Ca)\
**Post date:** [May 18, 2012, 8:48pm UTC](https://www.ruby-forum.com/t/chain-scopes-with-or/219860/2 "2012-05-18T20:48:48Z")

</div>

AFAIK, something like this should work:

def find\_visibles  
find\_in\_coverage | find\_known\_missing  
end

On Fri, May 18, 2012 at 10:53 PM, Gustavo de S Carvalho H. \<  
removed\_email\_address@domain.invalid\> wrote:

> “find\_in\_coverage” and “find\_known\_missing” scopes, like that:
> 
> –  
> You received this message because you are subscribed to the Google G.  
> “Ruby on Rails: Talk” group.  
> To post to this group, send email to removed\_email\_address@domain.invalid.  
> To unsubscribe from this group, send email to  
> removed\_email\_address@domain.invalid.  
> For more options, visit this group at  
> [http://groups.google.com/group/rubyonrails-talk?hl=en](http://groups.google.com/group/rubyonrails-talk?hl=en).

–

- Aziz M. Bookwala

Website [http://azizmb.in/](http://azizmb.in/) | Twitter [https://twitter.com/azizbookwala](https://twitter.com/azizbookwala)  
|  
Github [http://github.com/azizmb](http://github.com/azizmb)

---

<div class="post-metadata">

**Author:** ![SSGustavo\_de\_SSS\_Ca](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/cab0a1/32.png) [@SSGustavo\_de\_SSS\_Ca](https://www.ruby-forum.com/u/SSGustavo_de_SSS_Ca)\
**Post date:** [May 18, 2012, 8:54pm UTC](https://www.ruby-forum.com/t/chain-scopes-with-or/219860/3 "2012-05-18T20:54:22Z")

</div>

To add to that, if you want to construct complex queries, you should  
have a  
look at arel [https://github.com/rails/arel](https://github.com/rails/arel).

On Sat, May 19, 2012 at 12:17 AM, azizmb.in [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > Hi all!  
> > scope :find\_in\_coverage, lambda { where('timestamp(assets.found\_at) \>=
> > 
> > –
> 
> –
> 
> - Aziz M. Bookwala
> 
> Website [http://azizmb.in/](http://azizmb.in/) | Twitter [https://twitter.com/azizbookwala](https://twitter.com/azizbookwala)  
> | Github [http://github.com/azizmb](http://github.com/azizmb)

–

- Aziz M. Bookwala

Website [http://azizmb.in/](http://azizmb.in/) | Twitter [https://twitter.com/azizbookwala](https://twitter.com/azizbookwala)  
|  
Github [http://github.com/azizmb](http://github.com/azizmb)

---

<div class="post-metadata">

**Author:** ![SSGustavo\_de\_SSS\_Ca](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/cab0a1/32.png) [@SSGustavo\_de\_SSS\_Ca](https://www.ruby-forum.com/u/SSGustavo_de_SSS_Ca)\
**Post date:** [May 22, 2012, 3:12am UTC](https://www.ruby-forum.com/t/chain-scopes-with-or/219860/4 "2012-05-22T03:12:34Z")

</div>

On 22 May 2012 01:58, Gustavo de S Carvalho H. \<  
removed\_email\_address@domain.invalid\> wrote:

> The problem of the first solution is that “find\_in\_coverage |  
> find\_known\_missing” combined that way does not return a scope. It returns  
> two arrays each and applies | operator on the result. See:  
> [Class: Array (Ruby 1.9.3)](http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-7C)
> 
> I’ve looked arel docs (in fact, I just found poor docs). Can you please  
> point me where in docs is explaining how I can construct such query?

Have you read the README for arel? ([GitHub - rails/arel: A Relational Algebra](https://github.com/rails/arel))

“The OR operator works like this:  
users.where(users[:name].eq(‘bob’).or(users[:age].lt(25)))”

I don’t think you can do this through scopes, so working arel is the  
best  
alternative, but it may just be more hassle than you need. If you want a  
really hacky solution, I’ve done stuff like this in the past:

recipe\_query = Recipe.where(“pastry\_id = 1”).where(“filling\_id = 1”)  
Recipe.where(recipe\_query.where\_values.join(" OR "))

That generates:  
SELECT “recipes”.\* FROM “recipes” WHERE (pastry\_id = 1 OR filling\_id =  
1)

That might give you some ideas. It goes without saying that this is some  
hacky stuff you’re getting into, so I’d tread carefully!

Jeremy W.  
[http://www.ihid.co.uk](http://www.ihid.co.uk)

---

<div class="post-metadata">

**Author:** ![SSGustavo\_de\_SSS\_Ca](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/cab0a1/32.png) [@SSGustavo\_de\_SSS\_Ca](https://www.ruby-forum.com/u/SSGustavo_de_SSS_Ca)\
**Post date:** [May 22, 2012, 3:00am UTC](https://www.ruby-forum.com/t/chain-scopes-with-or/219860/5 "2012-05-22T03:00:15Z")

</div>

The problem of the first solution is that “find\_in\_coverage |  
find\_known\_missing” combined that way does not return a scope. It  
returns  
two arrays each and applies | operator on the result. See:

> **[Class: Array (Ruby 1.9.3)](https://ruby-doc.org/core-1.9.3/Array.html)**
>
> Class : Array - Ruby 1.9.3

I’ve looked arel docs (in fact, I just found poor docs). Can you please  
point me where in docs is explaining how I can construct such query?

Thanks for you attention,  
Gustavo

---

<div class="post-metadata">

**Author:** ![SSGustavo\_de\_SSS\_Ca](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/cab0a1/32.png) [@SSGustavo\_de\_SSS\_Ca](https://www.ruby-forum.com/u/SSGustavo_de_SSS_Ca)\
**Post date:** [May 22, 2012, 7:49pm UTC](https://www.ruby-forum.com/t/chain-scopes-with-or/219860/6 "2012-05-22T19:49:29Z")

</div>

@Rogerio: This way the scopes are merged with AND not OR

@Jeremy: I’ve read README and I haven’t found a way to join scopes with  
OR,  
as you mentioned. The only way I found is to join attributes with OR,  
not  
scopes. I’ve tried that hack (where\_clauses.join(‘OR’)) before too. The  
problem is that, for some reason, it don’t work when we use the scope  
chained with a association.

I’ve googled a lot and I found a lot of people complaining about this  
missing feature. I’m a big fan of Rails, but it is a pitty that Rails  
doesn’t give any simple way to do that. I really want to avoid that, but  
the best solution that I can see is to duplicate the code of the first  
two  
scopes on find\_visibles.

Thanks,  
Gustavo

---

<div class="post-metadata">

**Author:** ![SSGustavo\_de\_SSS\_Ca](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/cab0a1/32.png) [@SSGustavo\_de\_SSS\_Ca](https://www.ruby-forum.com/u/SSGustavo_de_SSS_Ca)\
**Post date:** [May 22, 2012, 3:26am UTC](https://www.ruby-forum.com/t/chain-scopes-with-or/219860/7 "2012-05-22T03:26:53Z")

</div>

try

escopo: find\_visibles, lambda { find\_in\_coverage.find\_know\_missing}

2012/5/21 Gustavo de S Carvalho H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> > > > I’ve googled all over and I couldn’t find anything about chaining  
> > > > scope :find\_unknown\_in\_coverage, where('assets.asset\_type\_id IS
> > > > 
> > > > Groups “Ruby on Rails: Talk” group.
> > > 
> > > - Aziz M. Bookwala  
> > > Website [http://azizmb.in/](http://azizmb.in/) | Twitter [https://twitter.com/azizbookwala](https://twitter.com/azizbookwala)
> 
> –  
> You received this message because you are subscribed to the Google G.  
> “Ruby on Rails: Talk” group.  
> To post to this group, send email to removed\_email\_address@domain.invalid.  
> To unsubscribe from this group, send email to  
> removed\_email\_address@domain.invalid.  
> For more options, visit this group at  
> [http://groups.google.com/group/rubyonrails-talk?hl=en](http://groups.google.com/group/rubyonrails-talk?hl=en).

–  
att,

Rogerio

A complicao se descomplica na mesma proporo que fazemos os ns se  
desatarem ao tecer o conhecimento do saber.

---

<div class="post-metadata">

**Author:** ![SSGustavo\_de\_SSS\_Ca](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/cab0a1/32.png) [@SSGustavo\_de\_SSS\_Ca](https://www.ruby-forum.com/u/SSGustavo_de_SSS_Ca)\
**Post date:** [May 22, 2012, 9:48pm UTC](https://www.ruby-forum.com/t/chain-scopes-with-or/219860/8 "2012-05-22T21:48:58Z")

</div>

U try ?

escopo: find\_visibles, lambda { find\_in\_coverage|find\_know\_  
missing}

2012/5/22 azizmb.in [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> On Tue, May 22, 2012 at 11:18 PM, Gustavo de S Carvalho H. \<
> 
> > I’ve googled a lot and I found a lot of people complaining about this
> > 
> > > > two arrays each and applies | operator on the result. See:
> > > > 
> > > > > > end
> > > > > > 
> > > > > > > I have an Asset model with the following scopes:  
> > > > > > > assets.asset\_type\_id IS NOT NULL’, Asset.found\_at\_limit) }
> > > > > > > 
> > > > > > > To unsubscribe from this group, send email to  
> > > > > > > Website [http://azizmb.in/](http://azizmb.in/) | Twitter[https://twitter.com/azizbookwala](https://twitter.com/azizbookwala)
> > > 
> > > –  
> > > You received this message because you are subscribed to the Google G.  
> > > –  
> > > removed\_email\_address@domain.invalid.  
> > > For more options, visit this group at  
> > > [http://groups.google.com/group/rubyonrails-talk?hl=en](http://groups.google.com/group/rubyonrails-talk?hl=en).

–  
att,

Rogerio

A complicao se descomplica na mesma proporo que fazemos os ns se  
desatarem ao tecer o conhecimento do saber.

---

<div class="post-metadata">

**Author:** ![SSGustavo\_de\_SSS\_Ca](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/cab0a1/32.png) [@SSGustavo\_de\_SSS\_Ca](https://www.ruby-forum.com/u/SSGustavo_de_SSS_Ca)\
**Post date:** [May 22, 2012, 9:43pm UTC](https://www.ruby-forum.com/t/chain-scopes-with-or/219860/9 "2012-05-22T21:43:20Z")

</div>

Hi Gustavo

Coincidentally, I was recently doing something similar. Older versions  
of  
rails used to evaluate my previous solution using " | " to an  
ActiveRelation. When this stopped I dont know, or maybe I am just  
mistaken.  
In any case, I finally settled on using the squeel  
gem[https://github.com/ernie/squeel](https://github.com/ernie/squeel),  
the arel docs, I agree are quite horrible.

There are examples on ‘OR’ queries with squeel on the github readme.

On Tue, May 22, 2012 at 11:18 PM, Gustavo de S Carvalho H. \<  
removed\_email\_address@domain.invalid\> wrote:

> doesn’t give any simple way to do that. I really want to avoid that, but
> 
> > > > have a look at arel [https://github.com/rails/arel](https://github.com/rails/arel).
> > > > 
> > > > > > class Asset \< ActiveRecord::Base  
> > > > > > end
> > > > > > 
> > > > > > For more options, visit this group at
> > > > 
> > > > You received this message because you are subscribed to the Google  
> > > > Groups “Ruby on Rails: Talk” group.  
> > > > att,  
> > > > To post to this group, send email to removed\_email\_address@domain.invalid.  
> > > > To unsubscribe from this group, send email to  
> > > > removed\_email\_address@domain.invalid.  
> > > > For more options, visit this group at  
> > > > [http://groups.google.com/group/rubyonrails-talk?hl=en](http://groups.google.com/group/rubyonrails-talk?hl=en).

–

- Aziz M. Bookwala

Website [http://azizmb.in/](http://azizmb.in/) | Twitter [https://twitter.com/azizbookwala](https://twitter.com/azizbookwala)  
|  
Github [http://github.com/azizmb](http://github.com/azizmb)
