我看到的问题本质
有一天,如果我没弄错的话,我已经看到了重用named_scope来定义另一个named_scope的例子。这样的事情(不记得确切的语法,但这正是我的问题):
named_scope :billable, :conditions => ...
named_scope :billable_by_tom, :conditions => {
:billable => true,
:user => User.find_by_name('Tom')
}
问题是:如果可能的话,确切的语法是什么?我找不回来了,谷歌也没有帮助。
一些解释
为什么我真的想要它,是因为我使用Searchlogic来定义复杂的搜索,这可能会产生这样的表达式:
Card.user_group_managers_salary_greater_than(100)
但是到处都是太久了。因为据我所知,Searchlogic只是动态定义了named_scopes,我想在Card类上设置一个named_scope,如下所示:
named_scope from_big_guys, { user_group_managers_salary_greater_than(100) }
- 这是我在named_scope中使用那个漫长的Searchlogic方法的地方。但是,再次,语法是什么?无法理解。
恢复
那么,named_scope嵌套(并且不意味着链接)实际上是否可能?
答案 0 :(得分:7)
您可以使用 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链接。
我在我的代码中使用它,它完美无缺。
我希望它有所帮助。
答案 1 :(得分:2)
我有同样的问题,好消息是在过去的五年里,Rails核心团队在范围部门取得了一些进展。
在Rails 3+中,你现在可以做到这一点,正如你所期望的那样:
scope :billable, where( due: true )
scope :billable_by_tom, -> { billable.where( user: User.find_by_name('Tom') ) }
Invoice.billable.to_sql #=> "... WHERE due = 1 ..."
Invoice.billiable_by_tom.to_sql #=> "... WHERE due = 1 AND user_id = 5 ..."
仅供参考,Rails 3+他们已将named_scope
重命名为scope
。我也使用Ruby 1.9语法。
如果有多个人是"可计费"除了汤姆"那么创建一个接受传递给块的名称参数的通用范围可能是有用的:
scope :billable_by, lambda { |name| billable.where( user: User.find_by_name( name ) ) }
然后你可以用:
来调用它Invoice.billable_by( "Tom" ).to_sql #=> "... WHERE due = 1 AND user_id = 5 ..."
顺便说一句,你可以看到我在奖励回合中使用了较旧的lambda
语法。这是因为我认为当您将一个参数传递给它时,新语法看起来很残忍:->( name ) { ... }
。
答案 2 :(得分:1)
请参阅此前question提出的时间。 lighthouse有一个补丁来满足您的要求。
答案 3 :(得分:1)
为什么一般只有scope
的{{1}}内容为Tom
,例如:
scope :by_tom, where( user: User.find_by_name('Tom') )
然后你就可以得到汤姆"可以收费的那些记录。用:
Record.billable.by_tom
答案 4 :(得分:0)
您可以使用方法组合一些named_scope,如:
def self.from_big_guys
self.class.user_group_managers_salary_greater_than(100)
end
此功能在Rails 3上添加了新语法(http://m.onkey.org/2010/1/22/active-record-query-interface)