有没有办法将命名范围组合成新的命名范围?
-
09-06-2019 - |
题
我有
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)
但它并不是特别可爱。
解决方案
好吧,我对 Rails 还很陌生,我不确定你到底要做什么,但如果你只是为了代码重用,为什么不使用常规的类方法呢?
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链接起来。
我在我的代码中使用了它并且它运行得很好。
我希望它有帮助。
@八打灵再也:你知道,我曾考虑过这一点,但后来放弃了它,因为我认为我以后无法链接 第三 命名范围,如下所示:
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.a.b
}
end
不隶属于 StackOverflow