Is there a way to merge named scopes into a new named scope?

I have

class Foo < ActiveRecord::Base named_scope :a, lambda { |a| :conditions => { :a => a } } named_scope :b, lambda { |b| :conditions => { :b => b } } end 

I would like to

 class Foo < ActiveRecord::Base named_scope :ab, lambda { |a,b| :conditions => { :a => a, :b => b } } end 

but I would rather do it in a dry way. I can get the same effect using

  Foo.a(something).b(something_else) 

but it is not particularly nice.

+6
ruby-on-rails
source share
6 answers

Well, I'm still new to rails, and I'm not quite sure what you are going for here, but if you are just going to use code reuse, why not use the regular class method?

 def self.ab(a, b) a(a).b(b) end 

You can make this more flexible by taking * args instead of a and b, and then maybe make one or the other extra. If you are stuck on named_scope, can you extend it to do the same?

Let me know if I totally disagree with what you want to do.

+2
source share

At least since 3.2 there is a smart solution:

 scope :optional, ->() {where(option: true)} scope :accepted, ->() {where(accepted: true)} scope :optional_and_accepted, ->() { self.optional.merge(self.accepted) } 
+5
source share

Having done this with the class method, you cannot associate it with the association proxy, for example:

 @category.products.ab(x, y) 

An alternative is to apply this patch to enable the: through option for named_scope:

 named_scope :a, :conditions => {} named_scope :b, :conditions => {} named_scope :ab, :through => [:a, :b] 
+1
source share

Yes Reusing named_scope to define another named_scope

I will copy it here for your convenience:

You can use proxy_options to reinstall one named_scope into another:

 class Thing #... named_scope :billable_by, lambda{|user| {:conditions => {:billable_id => user.id } } } named_scope :billable_by_tom, lambda{ self.billable_by(User.find_by_name('Tom').id).proxy_options } #... end 

Thus, it can be attached to other named_scopes.

I use this in my code and it works great.

Hope this helps.

+1
source share

@ PJ : you know, I thought about it, but rejected it because I thought I couldn’t be able to connect to the third named area later, for example like this:

 Foo.ab(x, y).c(z) 

But since ab(x, y) returns all b(y) , I think the chain will work. A way to make me rethink the obvious!

0
source share

Departure:

http://github.com/binarylogic/searchlogic

Impressive!

Specifically:

 class Foo < ActiveRecord::Base #named_scope :ab, lambda { |a,b| :conditions => { :a => a, :b => b } } # alias_scope, returns a Scope defined procedurally alias_scope :ab, lambda { Foo.ab } end 
0
source share

All Articles