named_scope features and gotchas

# Examples mostly taken from Ryan Daigle's blog.
# http://ryandaigle.com/articles/2008/3/24/what-s-new-in-edge-rails-has-finder-functionality
# this shall serve as a reminder for me!

# WORKS but actually breaks coding conventions
# well, at least in most cases if you respect print margins ;)
# (multiline blocks/lambdas(?) are supposed to be enclosed in do/end

named_scope :created_by_account, lambda { |account|
  { :conditions => [ "created_by = ?", account.id ] }
}

# DOES NOT WORK
# ArgumentError: tried to create Proc object without a block
# Most probably this is due to the way that named_scope extensions can be defined

named_scope :created_by_account, lambda do |account|
  { :conditions => [ "created_by = ?", account.id ] }
end

# named_scope extensions
# I guess because of the way do/end is used here,
# it is not possible to use do/end with lambda

named_scope :inactive, :conditions => {:active => false} do
  def activate
    each { |i| i.update_attribute(:active, true) }
  end
end

# original comment by Pratik Naik on March 27, 2008 @ 08:56 PM

named_scope :recent, :conditions => ['created_at > ?', 1.week.ago]

# That is really a bad example. As the conditions gets evaluated at load time,
# it’ll end up giving you inaccurate results in production
# where models get loaded only once.

# "Correct" way would be :

named_scope :recent, lambda {
  { :conditions => ['created_at > ?', 1.minute.ago] }
}

# Store named scopes
active = User.scoped(:conditions => {:active => true})
recent = User.scoped(lambda { { :conditions => ['created_at > ?', 1.minute.ago] } })
recent_active = recent.active
recent_active.each { |u| ... }

# count and statistic methods

user.active.recent.count #=> 23
user.active.recent.sum(:age) #=> 391


Leave a Reply

Formatting: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>