有没有办法将命名范围合并到一个新的命名范围?

我有

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

我想要

 class Foo  { :a => a, :b => b } } end 

但我更愿意以干燥的方式做到这一点。 我可以通过使用获得相同的效果

  Foo.a(something).b(something_else) 

但它并不是特别可爱。

好吧,我还是铁杆新手,我不确定你到底要做什么,但如果你只是为了代码重用,为什么不使用常规类方法呢?

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

您可以通过使用* args而不是a和b来使其更灵活,然后可能使一个或另一个可选。 如果你坚持使用named_scope,你不能扩展它以做同样的事情吗?

如果我完全偏离你想要做的事情,请告诉我。

至少从3.2开始就有一个聪明的解决方案:

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

通过使其成为类方法,您将无法将其链接到关联代理,例如:

 @category.products.ab(x, y) 

另一种方法是应用此补丁来为named_scope启用:through选项:

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

是重用named_scope来定义另一个named_scope

为方便起见,我将其复制到此处:

您可以使用proxy_options将一个named_scope回收到另一个:

 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 

这样它就可以与其他named_scopes链接。

我在我的代码中使用它,它完美地工作。

我希望它有所帮助。

@ PJ :你知道,我考虑过这个问题,但是因为我认为我以后无法链接到第三个命名范围,所以我认为是这样的:

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

但由于ab(x, y)返回b(y)将返回的任何内容,我认为该链可行。 让我重新思考明显的方法!

查看:

http://github.com/binarylogic/searchlogic

令人印象深刻!

再具体一点:

 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