How great is named_scope?

If you haven't used named_scope in Rails 2.1+ yet, I suggest you learn about it ASAP. Prior versions of Rails had a plugin that could perform similar functions, but it's nice to have it part of the core system. What does it do?

It does just what it says. It gives you a way to utilize the power of with_scope but name it. The best way to show it is with an example.

Let's say you have a user model. Users have a gender attribute and a activated flag. When operating on your user object, you could sprinkle your code with something like:

users = User.find(:all, :conditions => "gender = 'M'")
activated_males = User.find(:all,
   :conditions => "gender = 'F' and activated = 1")

Or...

You could do this:

class User < ActiveRecord::Base
  named_scope :activated,  :conditions => "users.activated = 1"
  named_scope :males, :conditions => "users.gender = 'M'"
  named_scope :females, :conditions => "users.gender = 'F'"
  # rest of your class
end

# Retrieved the activated users
users = User.activated
activated_males = User.activated.males

Note that you can string them together. You can also use all finder methods and the options will be merged together.

new_males = User.activated.males.find(:all,
   :conditions => ["users.created_at > ?", 2.days.ago])

I can also get a little fancy and add an argument:

named_scope :recent, lambda
   { |*args| {:conditions => ["created_at >= ?", (args.first || 1.day.ago)] } }

Now, the previous example is:

new_males = User.activated.males.recent(2.days.ago)

In the end, your code is far more readable, safer, DRY, and easier to maintain. It's a win all around.