7

我有

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

但我更喜欢以干燥的方式来做。我可以通过使用获得相同的效果

 Foo.a(something).b(something_else)

但它不是特别可爱。

4

6 回答 6

12

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

scope :optional, ->() {where(option: true)}
scope :accepted, ->() {where(accepted: true)}
scope :optional_and_accepted, ->() { self.optional.merge(self.accepted) }
于 2015-05-29T15:32:10.110 回答
2

好吧,我对 Rails 还是很陌生,我不确定你到底要在这里做什么,但如果你只是为了代码重用,为什么不使用常规的类方法呢?


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

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

让我知道我是否完全不了解您想要做的事情。

于 2008-08-27T17:50:49.600 回答
1

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

@category.products.ab(x, y)

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

named_scope :a, :conditions => {}
named_scope :b, :conditions => {}
named_scope :ab, :through => [:a, :b]
于 2009-05-11T10:24:35.703 回答
1

重用 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 链接。

我在我的代码中使用它并且它工作得很好。

我希望它有所帮助。

于 2010-07-20T12:53:57.280 回答
0

@ PJ:你知道,我曾考虑过这一点,但因为我认为我以后无法在第三个命名范围上进行链接,所以将其驳回,如下所示:

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

但既然ab(x, y)返回任何b(y)会返回的东西,我认为链条会起作用。让我重新思考显而易见的方法!

于 2008-08-27T18:08:52.457 回答
0

查看:

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.a.b
  }
end
于 2010-09-08T23:04:51.077 回答