jdkealy
jdkealy

Reputation: 4907

Eager loading not loading in rails

Hi am I missing something here? I read the docs on including joins on load and tried the following below. You can see that when I use "include", the included join does not output the desired data, however when I explicitly call the join model after the fact, you can see there is the desired data. Below are my models and behavior in IRB:

class Appearance < ActiveRecord::Base
  belongs_to :photo
  belongs_to :person
end


class Photo < ActiveRecord::Base
  belongs_to :event
  has_many :appearances, order: 'position'
  has_many :people, :through => :appearances
end


class PhotosController < ApplicationController
  def index
    @event            = Event.find(params[:event])
    @photos           = @event.photos.includes(:people, :appearances)
    # this does not show any appearance records, however this does
    # @photos           = @event.photos.first.people
  end
end

#IN IRB
 Photo.find(51941, :include => [:people, :appearances])
  Photo Load (0.4ms)  SELECT `photos`.* FROM `photos` WHERE `photos`.`id` = 51941 LIMIT 1
  Appearance Load (0.3ms)  SELECT `appearances`.* FROM `appearances` WHERE `appearances`.`photo_id` IN (51941) ORDER BY position
  Person Load (0.2ms)  SELECT `people`.* FROM `people` WHERE `people`.`id` IN (12103)

 => #<Photo id: 51941, time_created: "165732-0500", copyright_notice: "", country_primary_location_name: "", date_created: "20110119", created_at: "2011-01-20 07:33:24", updated_at: "2011-01-20 21:17:41", event_id: 602, position: 102, visible: nil, filename: "RAS_4824.JPG", folder: "", image: nil, image_file_name: nil, image_content_type: nil, image_file_size: nil, image_updated_at: nil> 

1.9.3p194 :036 > Photo.find(51941).appearances
  Photo Load (0.4ms)  SELECT `photos`.* FROM `photos` WHERE `photos`.`id` = 51941 LIMIT 1
  Appearance Load (0.4ms)  SELECT `appearances`.* FROM `appearances` WHERE `appearances`.`photo_id` = 51941 ORDER BY position
 => [#<Appearance id: 73654, photo_id: 51941, person_id: 12103, created_at: "2011-01-20 07:33:24", updated_at: "2011-01-20 07:33:24", position: 1>] 

Upvotes: 0

Views: 1325

Answers (1)

Chris Salzberg
Chris Salzberg

Reputation: 27374

I think you're misunderstanding the point of includes. Using includes (or the include option to find) tells rails to load the association from the DB at the same time that it loads the parent. This is happening in your IRB session, as you can see from the two lines:

Appearance Load (0.3ms)  SELECT `appearances`.* FROM `appearances` WHERE `appearances`.`photo_id` IN (51941) ORDER BY position
Person Load (0.2ms)  SELECT `people`.* FROM `people` WHERE `people`.`id` IN (12103)

The fact that you don't see the associated records when you output the result of find to the console is just a result of the inspect method, which does not (by default) show you data for all associations (which in general would be a huge amount of data).

When you input Photo.find(51941).appearances you are inspecting not a photo but the appearances association (an array), which is why you can see result in the IRB console.

If you want to test that include is working, first assign the photo to a variable:

photo = Photo.find(51941, :include => [:people, :appearances])
Photo Load (0.4ms)  SELECT `photos`.* FROM `photos` WHERE `photos`.`id` = 51941 LIMIT 1
Appearance Load (0.3ms)  SELECT `appearances`.* FROM `appearances` WHERE `appearances`.`photo_id` IN (51941) ORDER BY position
Person Load (0.2ms)  SELECT `people`.* FROM `people` WHERE `people`.`id` IN (12103)

You should see SQL statements not only for photos, but also for associated people and appearances. This is a sign that rails has eager-loaded these associations.

If you then get the associations with photo.appearances and you should not see any SQL queries, because the association is already loaded from the DB:

1.9.3p194 :036 > photo.appearances
=> [#<Appearance id: 73654, photo_id: 51941, person_id: 12103, created_at: "2011-01-20 07:33:24", updated_at: "2011-01-20 07:33:24", position: 1>] 

If you had not used include, you would have seen an SQL query before the result:

1.9.3p194 :036 > photo.appearances
Appearance Load (0.3ms)  SELECT `appearances`.* FROM `appearances` WHERE `appearances`.`photo_id` IN (51941) ORDER BY position
=> [#<Appearance id: 73654, photo_id: 51941, person_id: 12103, created_at: "2011-01-20 07:33:24", updated_at: "2011-01-20 07:33:24", position: 1>] 

Upvotes: 1

Related Questions