Should includes work with a query that returns the same object more than once?

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!

@photos = Photo.includes(comments: :person).all

Thanks, but that’s not what I’m trying to do. Photo.joins(:comments) returns a Photo for each Comment; if a Photo has two Comments I want it to appear twice in the query result. (That seems foolish but, as I said in my original post, this is cut down from a much larger query where this behavior is actually useful.) What you suggest gives me only one of each Photo regardless of its number of Comments. How can I get includes to work with my query (or another query with the same behavior), or can I?