Chain scopes with OR

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

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. <
[email protected]> 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 [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en.

  • Aziz M. Bookwala

Website http://azizmb.in/ | Twitter https://twitter.com/azizbookwala
|
Github http://github.com/azizmb

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

On Sat, May 19, 2012 at 12:17 AM, azizmb.in [email protected] wrote:

Hi all!
scope :find_in_coverage, lambda { where('timestamp(assets.found_at) >=

  • Aziz M. Bookwala

Website http://azizmb.in/ | Twitter https://twitter.com/azizbookwala
| Github http://github.com/azizmb

  • Aziz M. Bookwala

Website http://azizmb.in/ | Twitter https://twitter.com/azizbookwala
|
Github http://github.com/azizmb

On 22 May 2012 01:58, Gustavo de S Carvalho H. <
[email protected]> 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)

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)

“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

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:

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

@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

try

escopo: find_visibles, lambda { find_in_coverage.find_know_missing}

2012/5/21 Gustavo de S Carvalho H. [email protected]

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.


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 [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
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.

U try ?

escopo: find_visibles, lambda { find_in_coverage|find_know_
missing}

2012/5/22 azizmb.in [email protected]

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/ | Twitterhttps://twitter.com/azizbookwala


You received this message because you are subscribed to the Google G.

[email protected].
For more options, visit this group at
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.

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
gemhttps://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. <
[email protected]> 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.

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 [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en.

  • Aziz M. Bookwala

Website http://azizmb.in/ | Twitter https://twitter.com/azizbookwala
|
Github http://github.com/azizmb