0

嗨,我在这里错过了什么吗?我阅读了有关在加载时包含连接的文档,并尝试了以下操作。您可以看到,当我使用“包含”时,包含的连接不会输出所需的数据,但是当我在事后显式调用连接模型时,您可以看到有所需的数据。以下是我在 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>] 
4

1 回答 1

1

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>] 
于 2012-09-03T02:36:55.427 回答