Read more

Caution: `.includes` can make `.ids` non-unique.

Klaus Weidinger
November 08, 2022Software engineer at makandra GmbH

This can happen with a very simple model:

class Note
  has_many :attachments
end
Illustration money motivation

Opscomplete powered by makandra brand

Save money by migrating from AWS to our fully managed hosting in Germany.

  • Trusted by over 100 customers
  • Ready to use with Ruby, Node.js, PHP
  • Proactive management by operations experts
Read more Show archive.org snapshot

Everything looks normal:

Note.all.to_a.size # => 8
Note.all.ids.size # => 8

Then .includes leads to weird results:

Note.all.includes(:attachments).to_a.size # => 8
Note.all.includes(:attachments).ids.size # => 12

If a note has 5 attachments, its id will be included 5 times.

With .preload it works as expected:

Note.all.preload(:attachments).to_a.size # => 8
Note.all.preload(:attachments).ids.size # => 8

Note

I created a bug report for this in the Rails project:
https://github.com/rails/rails/issues/46455 Show archive.org snapshot

Posted by Klaus Weidinger to makandra dev (2022-11-08 13:46)