Skip to content

Commit a37b1df

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 d9098b6 commit a37b1df

File tree

2 files changed

+44
-12
lines changed

2 files changed

+44
-12
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: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,6 @@
180180
expect(Author.includes(:books => :author_name).references(:books)).to preload_values(:first_book_author_name, author_name)
181181
expect(Author.includes(:books => [:author_name]).references(:books)).to preload_values(:first_book_author_name, author_name)
182182
expect(Author.includes(:books => {:author_name => {}}).references(:books)).to preload_values(:first_book_author_name, author_name)
183-
end
184-
185-
it "uses preloaded fields" do
186-
expect(Author.includes(:books => :author_name).references(:books)).to preload_values(:first_book_author_name, author_name)
187-
expect(Author.includes(:books => [:author_name]).references(:books)).to preload_values(:first_book_author_name, author_name)
188-
expect(Author.includes(:books => {:author_name => {}}).references(:books)).to preload_values(:first_book_author_name, author_name)
189183
inc = Author.virtual_includes(:first_book_author_name)
190184
expect(Author.includes(inc).references(:books)).to preload_values(:first_book_author_name, author_name)
191185
end
@@ -308,10 +302,6 @@
308302
it "uses included fields" do
309303
expect(preloaded(Author.all.to_a, :books => :author_name)).to preload_values(:first_book_author_name, author_name)
310304
end
311-
312-
it "uses preloaded fields" do
313-
expect(preloaded(Author.all.to_a, :books => :author_name)).to preload_values(:first_book_author_name, author_name)
314-
end
315305
end
316306

317307
context "preloads virtual_reflection with includes" do
@@ -386,11 +376,49 @@
386376
end
387377
end
388378

379+
describe ".eager_load" do
380+
it "preloads standard associations (:books)" do
381+
expect(Author.eager_load(:books)).to preload_values(:first_book_name, book_name)
382+
expect(Author.eager_load([:books])).to preload_values(:first_book_name, book_name)
383+
expect(Author.eager_load([[:books]])).to preload_values(:first_book_name, book_name)
384+
expect(Author.eager_load(:books => {})).to preload_values(:first_book_name, book_name)
385+
end
386+
387+
it "preloads associations (:uses => :books)" do
388+
expect(Author.eager_load(:first_book_name)).to preload_values(:first_book_name, book_name)
389+
expect(Author.eager_load([:first_book_name])).to preload_values(:first_book_name, book_name)
390+
expect(Author.eager_load([[:first_book_name]])).to preload_values(:first_book_name, book_name)
391+
expect(Author.eager_load(:first_book_name => {})).to preload_values(:first_book_name, book_name)
392+
end
393+
end
394+
395+
describe ".preload" do
396+
it "preloads standard associations (:books)" do
397+
expect(Author.preload(:books)).to preload_values(:first_book_name, book_name)
398+
expect(Author.preload([:books])).to preload_values(:first_book_name, book_name)
399+
expect(Author.preload([[:books]])).to preload_values(:first_book_name, book_name)
400+
expect(Author.preload(:books => {})).to preload_values(:first_book_name, book_name)
401+
end
402+
403+
it "preloads associations (:uses => :books)" do
404+
expect(Author.preload(:first_book_name)).to preload_values(:first_book_name, book_name)
405+
expect(Author.preload([:first_book_name])).to preload_values(:first_book_name, book_name)
406+
expect(Author.preload([[:first_book_name]])).to preload_values(:first_book_name, book_name)
407+
expect(Author.preload(:first_book_name => {})).to preload_values(:first_book_name, book_name)
408+
end
409+
end
410+
389411
context "preloads virtual_reflection with preloader" do
390412
it "preloads virtual_reflection (:uses => :books)" do
391413
expect(preloaded(Author.all.to_a, :named_books)).to preload_values(:named_books, named_books)
392414
end
393415

416+
it "preloads virtual_reflection ([:books])" do
417+
expect(preloaded(Author.all.to_a, :books)).to preload_values(:named_books, named_books)
418+
expect(preloaded(Author.all.to_a, [:books])).to preload_values(:named_books, named_books)
419+
expect(preloaded(Author.all.to_a, :books => {})).to preload_values(:named_books, named_books)
420+
end
421+
394422
it "preloads virtual_reflection (:uses => {:books => :author_name})" do
395423
expect(preloaded(Author.all.to_a, :books_with_authors)).to preload_values(:books_with_authors, named_books)
396424
end

0 commit comments

Comments
 (0)