Rails 2.3.x – 这个ActiveRecord范围如何工作?

我正在处理的项目中有一个named_scope,如下所示:

# default product scope only lists available and non-deleted products ::Product.named_scope :active, lambda { |*args| Product.not_deleted.available(args.first).scope(:find) } 

最初的named_scope是有道理的。 这里令人困惑的部分是.scope(:find)如何工作。 这显然是调用另一个命名范围(not_deleted),然后应用.scope(:find)。 什么/如何.scope(:find)在这里工作?

快速回答

 Product.not_deleted.available(args.first) 

是一个命名范围本身,由两个命名范围组合而成。

scope(:find)获取命名范围(或范围组合)的条件,您可以使用它们来创建新的命名范围。

所以通过例子:

 named_scope :active, :conditions => 'active = true' named_scope :not_deleted, :conditions => 'deleted = false' 

然后你写

 named_scope :active_and_not_deleted, :conditions => 'active = true and deleted = false' 

或者,你可以写

 named_scope :active_and_not_deleted, lambda { self.active.not_deleted.scope(:find) } 

这是相同的。 我希望这说清楚。

请注意,这在rails 3中变得更简单(更干净),您只需编写

 scope :active_and_not_deleted, active.not_deleted 

Scope是ActiveRecord :: Base上的一个方法,它返回传入方法的当前范围(如果此时要运行它,实际上将用于构建查询)。

 # Retrieve the scope for the given method and optional key. def scope(method, key = nil) #:nodoc: if current_scoped_methods && (scope = current_scoped_methods[method]) key ? scope[key] : scope end end 

因此,在您的示例中,lambda在合并所有其他命名范围后返回Product.find调用的范围。

我有一个named_scope:

 named_scope :active, {:conditions => {:active => true}} 

在我的控制台输出中, Object.active.scope(:find)返回:

 {:conditions => {:active => true}}