There's a named_scope in a project I'm working on that looks like the following:
# default p开发者_高级运维roduct scope only lists available and non-deleted products
::Product.named_scope :active, lambda { |*args|
Product.not_deleted.available(args.first).scope(:find)
}
The initial named_scope makes sense. The confusing part here is how .scope(:find) works. This is clearly calling another named scope (not_deleted), and applying .scope(:find) afterwards. What/how does .scope(:find) work here?
A quick answer
Product.not_deleted.available(args.first)
is a named-scope itself, formed by combining both named scopes.
scope(:find)
gets the conditions for a named-scope (or combination of scopes), which you can in turn use to create a new named-scope.
So by example:
named_scope :active, :conditions => 'active = true'
named_scope :not_deleted, :conditions => 'deleted = false'
then you write
named_scope :active_and_not_deleted, :conditions => 'active = true and deleted = false'
or, you could write
named_scope :active_and_not_deleted, lambda { self.active.not_deleted.scope(:find) }
which is identical. I hope that makes it clear.
Note that this has become simpler (cleaner) in rails 3, you would just write
scope :active_and_not_deleted, active.not_deleted
Scope is a method on ActiveRecord::Base that returns the current scope for the method passed in (what would actually be used to build the query if you were to run it at this moment).
# 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
So in your example, the lambda returns the scope for a Product.find
call after merging all the other named scopes.
I have a named_scope:
named_scope :active, {:conditions => {:active => true}}
In my console output, Object.active.scope(:find)
returns:
{:conditions => {:active => true}}
精彩评论