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.

3 Responses to “Add an ActiveRecord scope for easier eager loading”

  1. Raphael Concil replied on November 11th, 2009 at 06:42 AM:

    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?

  2. @Raphael: Sure, lib is a fine place. On one project I have this code in lib/active_record/eager_load.rb. I also have a file in config/initializers/lib.rb where the file is loaded:

    require 'active_record/eager_load'
    
  3. Raphael Concil replied on November 12th, 2009 at 02:48 AM:

    @Jim: Thank you for your help, now I can use this code for every model and it is working like a charm.

Leave a Reply