My app has models Person, Photo, Comment. A Comment has_many Photos and
a
Photo has_many People.
In the console, with a database with some data in it and the
ActiveRecord
logger sent to STDOUT …
First, to show what’s in the data:
irb(main):003:0> Photo.joins(:comments).order(:id).limit(2).map &:id
D, [2014-08-05T18:19:10.528376 #24027] DEBUG – : Photo Load (20.6ms)
SELECT photos
.* FROM photos
INNER JOIN comments
ON
comments
.photo_id
= photos
.id
ORDER BY photos
.id
ASC LIMIT
2
=> [1, 1]
Photo.joins(:comments).order(:id).limit(2) returns the same photo twice,
because it has two comments. That’s what I want. (This is cut down from
a
much larger query where this behavior is actually useful.) Now for the
problem:
irb(main):001:0>
Photo.joins(:comments).includes(:person).order(:id).limit(2).each { |f|
puts f.person.username }; nil
D, [2014-08-05T18:17:44.613676 #24027] DEBUG – : Photo Load (0.6ms)
SELECT photos
.* FROM photos
INNER JOIN comments
ON
comments
.photo_id
= photos
.id
ORDER BY photos
.id
ASC LIMIT
2
D, [2014-08-05T18:17:44.811715 #24027] DEBUG – : Person Load (0.3ms)
SELECT people
.* FROM people
WHERE people
.id
IN (1)
user1
D, [2014-08-05T18:17:44.845897 #24027] DEBUG – : Person Load (0.6ms)
SELECT people
.* FROM people
WHERE people
.id
= 1 LIMIT 1
user1
Even though I said includes(:person), and it did cause ActiveRecord to
issue the second query to get all the people, when I retrieve the second
Photo’s Person ActiveRecord has to query it again. With a production
query
with many more photos and people it’s very slow.
Is this a bug? Is includes not supported with a query that returns the
same
object more than once? Is there a way around the N + 1 queries?
Thanks!