Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
188 views
in Technique[技术] by (71.8m points)

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>] 
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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>] 

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...