Skip to content

Commit 17cb22d

Browse files
committed
Better detection of standard preload
This ends up being an optimization. But when preloading `[:association]`, it runs a separate preloader on `:association`. This skips the interim step
1 parent 5013d28 commit 17cb22d

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

lib/active_record/virtual_attributes/virtual_fields.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,12 @@ def call
152152

153153
# convert the includes with virtual attributes to includes with proper associations
154154
records_by_assoc = records.group_by { |rec| assoc_cache[rec.class] }
155-
# if these are the same includes, then do the preloader work
156-
return super if records_by_assoc.size == 1 && records_by_assoc.keys.first == associations
155+
# If the association were already translated, then short circuit / do the standard preloader work.
156+
# When replace_virtual_fields removes the outer array, match that too.
157+
if records_by_assoc.size == 1 &&
158+
(associations == records_by_assoc.keys.first || associations == [records_by_assoc.keys.first])
159+
return super
160+
end
157161

158162
# for each of the associations, run a preloader
159163
records_by_assoc.each do |klass_associations, klass_records|

spec/virtual_includes_spec.rb

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,11 +386,63 @@
386386
end
387387
end
388388

389+
describe ".eager_load" do
390+
it "preloads standard associations (:books)" do
391+
expect(Author.eager_load(:books)).to preload_values(:first_book_name, book_name)
392+
expect(Author.eager_load([:books])).to preload_values(:first_book_name, book_name)
393+
expect(Author.eager_load([[:books]])).to preload_values(:first_book_name, book_name)
394+
expect(Author.eager_load(:books => {})).to preload_values(:first_book_name, book_name)
395+
end
396+
397+
it "preloads associations (:uses => :books)" do
398+
expect(Author.eager_load(:first_book_name)).to preload_values(:first_book_name, book_name)
399+
expect(Author.eager_load([:first_book_name])).to preload_values(:first_book_name, book_name)
400+
expect(Author.eager_load([[:first_book_name]])).to preload_values(:first_book_name, book_name)
401+
expect(Author.eager_load(:first_book_name => {})).to preload_values(:first_book_name, book_name)
402+
end
403+
404+
it "preloads standard associations (:books)" do
405+
expect(Author.eager_load(:books)).to preload_values(:first_book_name, book_name)
406+
expect(Author.eager_load([:books])).to preload_values(:first_book_name, book_name)
407+
expect(Author.eager_load([[:books]])).to preload_values(:first_book_name, book_name)
408+
expect(Author.eager_load(:books => {})).to preload_values(:first_book_name, book_name)
409+
end
410+
end
411+
412+
describe ".preload" do
413+
it "preloads standard associations (:books)" do
414+
expect(Author.preload(:books)).to preload_values(:first_book_name, book_name)
415+
expect(Author.preload([:books])).to preload_values(:first_book_name, book_name)
416+
expect(Author.preload([[:books]])).to preload_values(:first_book_name, book_name)
417+
expect(Author.preload(:books => {})).to preload_values(:first_book_name, book_name)
418+
end
419+
420+
it "preloads associations (:uses => :books)" do
421+
expect(Author.preload(:first_book_name)).to preload_values(:first_book_name, book_name)
422+
expect(Author.preload([:first_book_name])).to preload_values(:first_book_name, book_name)
423+
expect(Author.preload([[:first_book_name]])).to preload_values(:first_book_name, book_name)
424+
expect(Author.preload(:first_book_name => {})).to preload_values(:first_book_name, book_name)
425+
end
426+
427+
it "preloads standard associations (:books)" do
428+
expect(Author.preload(:books)).to preload_values(:first_book_name, book_name)
429+
expect(Author.preload([:books])).to preload_values(:first_book_name, book_name)
430+
expect(Author.preload([[:books]])).to preload_values(:first_book_name, book_name)
431+
expect(Author.preload(:books => {})).to preload_values(:first_book_name, book_name)
432+
end
433+
end
434+
389435
context "preloads virtual_reflection with preloader" do
390436
it "preloads virtual_reflection (:uses => :books)" do
391437
expect(preloaded(Author.all.to_a, :named_books)).to preload_values(:named_books, named_books)
392438
end
393439

440+
it "preloads virtual_reflection ([:books])" do
441+
expect(preloaded(Author.all.to_a, :books)).to preload_values(:named_books, named_books)
442+
expect(preloaded(Author.all.to_a, [:books])).to preload_values(:named_books, named_books)
443+
expect(preloaded(Author.all.to_a, :books => {})).to preload_values(:named_books, named_books)
444+
end
445+
394446
it "preloads virtual_reflection (:uses => {:books => :author_name})" do
395447
expect(preloaded(Author.all.to_a, :books_with_authors)).to preload_values(:books_with_authors, named_books)
396448
end

0 commit comments

Comments
 (0)