Saturday, October 25, 2008

Rails 2.0 - named_scope rocks..

In Rails 2.0, ActiveRecord has a feature called named scope, which makes things easier..

With named scope, you can give a name to scope or condition..For instance, if you have a model called "Comment" and say it has a database column called published, published_at, then the model with namedscope definitions:

    1 class Comment < ActiveRecord::Base
2 named_scope :published, :conditions => {:published => true}
3 named_scope :limit, lambda {|count| :limit => count}
4 named_scope :in_last_ten_days, lambda{:conditions => ["published_at > ?", 10.days.ago ]}
5 named_scope :order_by_published_time, :order => "published_at"
6 end
Comment.published - return all the comments which are published.
Comment.in_last_ten_days - returns all the comment objects which has pusblished_at time within last 10 days.
Comment.limit(10) - returns 10 comment objects.
Comment.order_by_published_time - returns all the comments in chronological order.

They just behaves as find methods on the receiver with options just as we pass to the find method..

But the specality about named_scope is "Named Scope can be COMBINED and it will FIRE ONLY ONE SQL QUERY with all the options combined"

Comment.order_by_published_time.limit(5) - returns top 5 comments in chronological order

For this operation one query is fired with ORDER BY and LIMIT clauses!!

With named_scope, we can also combine our own find method, like
Comment.order_by_published_time.find(:all, :condition => {:published_at => Time.parse "14 Jun 2008 15:38:06"})

Again, say we have another model called News and it has "has many" relationship with comment,

    1 class News < ActiveRecord::Base
2 has_many :comments
3 end
Then we can call the named_scope of comment for array of comments which are related to a news object, like

news = News.first

For this operation also, only one query is fired for finding all the comments of that news which are published..

So named_scope can also be called for associated children objects of a parent model!!

No comments: