有没有一种方法可以将命名范围合并到新的命名范围中?

时间:2020-03-05 18:43:32  来源:igfitidea点击:

我有

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

我想要

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

但我更喜欢以DRY方式进行。我可以通过使用获得相同的效果

Foo.a(something).b(something_else)

但这不是特别可爱。

解决方案

回答

回答

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

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. 

Answer

@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)

一种替代方法是应用此修补程序以启用named_scope的:through选项:

@category.products.ab(x, y)

回答

是重复使用named_scope来定义另一个named_scope

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

我们可以使用proxy_options将一个named_scope回收为另一个:

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

这样,它可以与其他named_scopes链接在一起。

我在代码中使用了它,并且效果很好。

希望对我们有所帮助。

回答

退房:

http://github.com/binarylogic/searchlogic

感人的!

再具体一点:

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

代码数量不匹配