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

纵饮孤独 提交于 2019-11-30 20:41:37

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


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

You could make that more flexible by taking *args instead of a and b, and then possibly make one or the other optional. If you're stuck on named_scope, can't you extend it to do much the same thing?

Let me know if I'm totally off base with what you're wanting to do.

At least since 3.2 there is a clever solution :

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

By making it a class method you won't be able to chain it to an association proxy, like:

@category.products.ab(x, y)

An alternative is applying this patch to enable a :through option for named_scope:

named_scope :a, :conditions => {}
named_scope :b, :conditions => {}
named_scope :ab, :through => [:a, :b]
Oinak

Yes Reusing named_scope to define another named_scope

I copy it here for your convenience:

You can use proxy_options to recycle 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

This way it can be chained with other named_scopes.

I use this in my code and it works perfectly.

I hope it helps.

James A. Rosen

@PJ: you know, I had considered that, but dismissed it because I thought I wouldn't be able to later chain on a third named scope, like so:

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

But since ab(x, y) returns whatever b(y) would return, I think the chain would work. Way to make me rethink the obvious!

Check out:

http://github.com/binarylogic/searchlogic

Impressive!

To be specific:

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.a.b
  }
end
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!