8

我所看到的问题本质

有一天,如果我没记错的话,我看到了一个重用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 嵌套(我的意思不是链接)实际上可能吗?

4

5 回答 5

8

您可以使用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:52:10.687 回答
2

请参阅之前在 SO 上提出的这个问题。灯塔有一个补丁可以满足您的要求。

于 2010-03-15T03:49:07.653 回答
2

导轨 3+

我也有同样的问题,好消息是在过去的五年里,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_scopescope. 我也在使用 Ruby 1.9 语法。

奖金回合:通用范围。

如果除了“Tom”之外还有多个“可计费”的人,那么创建一个接受传递到块中的名称参数的通用范围可能很有用:

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 ) { ... }.

于 2015-04-13T14:01:26.577 回答
1

链范围。

为什么一般不使用scopefor 东西Tom,例如:

scope :by_tom, where( user: User.find_by_name('Tom') )

然后您可以通过以下方式获取“Tom 可计费”的那些记录:

Record.billable.by_tom
于 2015-05-29T23:30:58.940 回答
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 )

于 2010-03-14T20:39:00.650 回答