ActiveRecord:嵌套关联急切加载不加载孙子对象

时间:2014-09-19 20:01:27

标签: ruby-on-rails activerecord ruby-on-rails-4 eager-loading

我在ActiveRecord中有以下关系:Annotation有很多AnnotationGroups,每个AnnotationNote都有一个has_many :annotation_groups, :dependent => :destroy (是的,笔记在AG' s,而不是基础Annos)。

Annotation.rb

belongs_to :annotation
has_one :annotation_note, :foreign_key => 'annotation_group_id'

AnnotationGroup.rb

belongs_to :annotation_group

AnnotationNote.rb

scope :flattened_by_group, ->(group_id) {
    includes(:annotation_groups => :annotation_note).where({
        'annotation_groups.group_id' => group_id
    })
}

现在,我试图加载一系列注释,他们的群组以及他们的群组'注意,使用以下范围:

Annotation.rb

Annotation.flattened_by_group(group.id).as_json()

以下是应该触发急切加载的调用:

SQL (0.6ms)  SELECT "annotations"."id" AS t0_r0, (annotations cols trimmed) "annotation_groups"."id" AS t1_r0, (anno_groups cols trimmed) "annotation_notes"."id" AS t2_r0, "annotation_notes"."document_id" AS t2_r1, "annotation_notes"."annotation_group_id" AS t2_r2, "annotation_notes"."note" AS t2_r3, "annotation_notes"."addressed" AS t2_r4, "annotation_notes"."created_at" AS t2_r5, "annotation_notes"."updated_at" AS t2_r6 FROM "annotations" 
LEFT OUTER JOIN "annotation_groups" ON "annotation_groups"."annotation_id" = "annotations"."id" 
LEFT OUTER JOIN "annotation_notes" ON "annotation_notes"."annotation_group_id" = "annotation_groups"."id" 
WHERE "annotation_groups"."group_id" = 81

SQL当然似乎可以提取足够的数据来完成工作:

as_json

以下是 def as_json(opts={}) anno_group = annotation_groups[0] opts.merge({:skip_groups => true}) canonical(opts).merge({ 'document_id' => document_id, 'account_id' => account_id, 'organization_id' => organization_id, 'annotation_group_id' => anno_group.id, 'approved_count' => anno_group.approved_count, 'qa_approved_by' => anno_group.qa_approved_by, 'qa_note' => anno_group.annotation_note ? anno_group.annotation_note.note : nil }) end 代码,我开始遇到问题:

annotation_groups[0]

anno_group.annotation_note执行时,不会触发任何查询,向我显示急切加载有效。但是,在includes检查(或其任何变体)时,每次执行一个新查询,获取该特定annotation_group的注释(即使只是检查对象是否为零)。

为什么子对象(AnnotationGroup)正在急切加载,而不是孙子(AnnotationNote),即使它的字段在{{1}}子句的查询中正确返回了?

== UPDATE =======

从下面的Rails eager loading逻辑中,我怀疑问题源于那些与DB中的任何内容都不匹配的记录(因此AnnotationNote没有数据,因此它没有创建)。有没有办法检查这个nil状态而不启动对DB的另一个查询?

1 个答案:

答案 0 :(得分:0)

因此,正如我从Rails逻辑中挖掘出来的那样,“渴望加载”#39;如果从表中加入的行的id为NULL,则不会为关联创建空白对象。检查对象是否是通过在关联上使用.nil?创建的,将运行查询以查找它,从而破坏了急切加载的目的。

因为它是has_one关系,检查它是否已加载并没有我能找到的奇特功能,例如loaded?has_many关系的影响。所以我最终要做的是检查annotation_note对象AnnotationGroup中是否存在annotation_cache。相关代码更改如下:

'qa_note' => anno_group.association_cache.keys.include?(:annotation_note) ? anno_group.annotation_note.note : nil