Reputation: 4907
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
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