急切加载未在导轨中加载 [英] Eager loading not loading in rails
问题描述
我在这里想念什么吗?我阅读了有关包括加载中的联接的文档,并尝试了以下方法。您可以看到,当我使用 include时,包含的联接不会输出所需的数据,但是当我在事实之后显式调用联接模型时,可以看到存在所需的数据。以下是我在IRB中的模型和行为:
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>]
推荐答案
我认为您误解了包括
。使用 includes
(或 include
选项进行查找)告诉rails同时从数据库加载关联。它加载父级。这是在您的IRB会话中发生的,从两行中可以看到:
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)
您没有看到的事实当您将 find
的结果输出到控制台时记录的记录只是 inspect
方法,该方法(默认情况下)不会向您显示所有关联的数据(一般来说,数据)。
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).
输入 Photo.find(51941).appearances
时,您检查的不是照片,而是外观关联(数组),这就是为什么您可以在IRB控制台中看到结果的原因。
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.
如果要测试 include
正在工作,首先将照片分配给变量:
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)
您不仅应该看到照片的SQL语句,而且还应该看到相关的SQL语句人和外表。这表明Rails渴望加载这些关联。
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.
如果您随后获得带有 photo.appearances
,并且您应该不看到任何SQL查询,因为关联已从数据库中加载:
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>]
如果您 not 未使用 include
,您将在结果之前看到一个SQL查询:
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>]
这篇关于急切加载未在导轨中加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!