1

我在ActiveRecord中有以下關係:Annotation有很多AnnotationGroups,其中每個都有AnnotationNote(是的,註釋在AG上,而不是在Annos基礎上)。ActiveRecord:嵌套關聯熱切加載不加載孫子對象

Annotation.rb

has_many :annotation_groups, :dependent => :destroy 

AnnotationGroup.rb現在

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

AnnotationNote.rb

belongs_to :annotation_group 

,我「米試圖急於負載串聯的註解,其羣體,他們羣體的」音符,用下列範圍:

Annotation.rb

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

這裏是調用應該觸發熱切負載:

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

的SQL肯定似乎拉開足夠的數據來完成工作:

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 

這裏是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檢查(或其任何變體)中,每次都會執行一個新查詢,爲該特定annotation_group提取註釋(即使僅檢查該對象是否爲零)。

即使在includes子句的查詢中正確返回其字段,爲什麼子對象(AnnotationGroup)正在被加載,而不是孫子(AnnotationNote)呢?

====== UPDATE =======

從Rails的渴望加載邏輯沿着以下,我懷疑從不會在DB匹配任何這些記錄的問題莖(所以AnnotationNote沒有數據,因此它不會被創建)。有沒有辦法檢查這個無狀態而不向數據庫發出另一個查詢?

+0

順便說一句,我的Rails的版本是4.1.0,在有任何影響的情況下。我正在尋找Rails的問題追蹤器,以查看4.1.0和當前版本之間是否存在類似的問題,但到目前爲止還沒有發現任何問題。 – roberttdev 2014-09-19 20:45:48

+0

我跑了一個臨時更新到Rails 4.1.6並給它一個鏡頭,它仍然遵循相同的邏輯。 – roberttdev 2014-09-19 21:37:20

回答

0

因此,從我通過Rails邏輯挖掘發現,如果從表中連接的行的ID爲NULL,'eager loading'不會爲關聯創建空白對象。檢查關聯是否使用關聯創建對象.nil?將運行查詢來查找它,從而破壞急切加載的目的。

因爲這是一個has_one關係,檢查它是否加載沒有我能找到的奇特功能,就像loaded?has_many關係一樣。所以我最終做的是檢查AnnotationGroup對象的annotation_cache中是否存在annotation_note。下面相關的代碼變化:

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

相關問題