简体   繁体   中英

Rails 2.3.x - how does this ActiveRecord scope work?

There's a named_scope in a project I'm working on that looks like the following:

 # default product 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}}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM