我在这里错过了什么吗?我阅读了关于加载加入的文档,并尝试了以下内容。您可以看到,当我使用" include"时,包含的连接不会输出所需的数据,但是当我在事后明确调用连接模型时,您可以看到存在所需的数据。以下是我在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>]
答案 0 :(得分:1)
我认为你误解了includes
的观点。使用includes
(或include
选项查找)告诉rails在加载父进程的同时从DB加载关联。这可以在您的IRB会话中进行,您可以从以下两行中看到:
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)
当您将find
的结果输出到控制台时,看关联记录的事实只是inspect
方法的结果,不(默认情况下)显示所有关联的数据(通常会有大量数据)。
当您输入Photo.find(51941).appearances
时,您正在检查的不是照片,而是检查外观关联(数组),这就是您可以在IRB控制台中查看结果的原因。
如果您想测试include
是否有效,请先将照片分配给变量:
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)
您不仅应该看到照片的SQL语句,还应该看到相关人员和外观的SQL语句。这表明rails已经急切地加载了这些关联。
如果您随后获得与photo.appearances
的关联,并且您不会看到任何SQL查询,因为该关联已经从数据库加载:
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>]
如果不使用include
,您会在结果之前看到SQL查询:
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>]