Add an ActiveRecord scope for easier eager loading
Posted October 28th, 2009; 3 comments.
In the optimization phase of a project, one of the first things I do is look for pages that could benefit from the use of ActiveRecord’s eager loading. Since named_scopes were introduced in Rails 2.1, most of my model loading has involved a chain of scopes, and it is always frustrating to have to change
@blogs = Blog.published.active
to
@blogs = Blog.published.active.scoped(:include => [:slugs, :topic => :slugs])
It’s a small difference, but one I’ve never really liked. It seems like an obvious choice would be to add a named_scope to all subclasses of ActiveRecord::Base and have that handle the :include parameter. I finally wrote the 11 lines of code required to do this today:
module ActiveRecord module EagerLoadScope def self.included(base) base.named_scope :eager_load, lambda { |*inclusion| {:include => inclusion} } end end end ActiveRecord::Base.class_eval { include ActiveRecord::EagerLoadScope }
And now that line looks like this:
@blogs = Blog.published.active.eager_load(:slugs, :topic => :slugs)
Again, it’s a small improvement, but one I consider worthwhile.
Hi,
I’d like to thank you for sharing this code. This is exactly what i was looking for. But I didn’t understand where to put this piece of code. Is it possible to insert it in the lib folder of my rails application?
Could you explain where to insert it?
@Raphael: Sure,
libis a fine place. On one project I have this code inlib/active_record/eager_load.rb. I also have a file inconfig/initializers/lib.rbwhere the file is loaded:@Jim: Thank you for your help, now I can use this code for every model and it is working like a charm.