4

I have been eager loading ActiveStorage attachments as follows:

Journey.includes(created_by_user: [profile_picture_attachment: :blob])

We have been using variants and every since we upgraded to Rails 6.1 and enabled tracking Active Storage variants in database, we notice n+1 queries in the logs because of a loop as follows:

Journey.includes(created_by_user: [profile_picture_attachment: :blob]).each do |j|
 j.created_by_user.profile_picture.variant(resize_to_fill: [32, 32]).processed
end
Journey Load (0.8ms)  SELECT "journeys".* FROM "journeys"
  User Load (0.7ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1  [["id", 607]]
  ActiveStorage::Attachment Load (0.6ms)  SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_type" = $1 AND "active_storage_attachments"."name" = $2 AND "active_storage_attachments"."record_id" = $3  [["record_type", "User"], ["name", "profile_picture"], ["record_id", 607]]
  ActiveStorage::Blob Load (0.6ms)  SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = $1  [["id", 144]]
  ActiveStorage::VariantRecord Load (0.5ms)  SELECT "active_storage_variant_records".* FROM "active_storage_variant_records" WHERE "active_storage_variant_records"."blob_id" = $1 AND "active_storage_variant_records"."variation_digest" = $2 LIMIT $3  [["blob_id", 144], ["variation_digest", "k9S9jJS87DbFgXD1sW9j5XkOr1c="], ["LIMIT", 1]]
  ActiveStorage::VariantRecord Load (0.5ms)  SELECT "active_storage_variant_records".* FROM "active_storage_variant_records" WHERE "active_storage_variant_records"."blob_id" = $1 AND "active_storage_variant_records"."variation_digest" = $2 LIMIT $3  [["blob_id", 144], ["variation_digest", "k9S9jJS87DbFgXD1sW9j5XkOr1c="], ["LIMIT", 1]]
  ActiveStorage::VariantRecord Load (0.5ms)  SELECT "active_storage_variant_records".* FROM "active_storage_variant_records" WHERE "active_storage_variant_records"."blob_id" = $1 AND "active_storage_variant_records"."variation_digest" = $2 LIMIT $3  [["blob_id", 144], ["variation_digest", "k9S9jJS87DbFgXD1sW9j5XkOr1c="], ["LIMIT", 1]]
  ActiveStorage::VariantRecord Load (0.5ms)  SELECT "active_storage_variant_records".* FROM "active_storage_variant_records" WHERE "active_storage_variant_records"."blob_id" = $1 AND "active_storage_variant_records"."variation_digest" = $2 LIMIT $3  [["blob_id", 144], ["variation_digest", "k9S9jJS87DbFgXD1sW9j5XkOr1c="], ["LIMIT", 1]]
  ActiveStorage::VariantRecord Load (0.5ms)  SELECT "active_storage_variant_records".* FROM "active_storage_variant_records" WHERE "active_storage_variant_records"."blob_id" = $1 AND "active_storage_variant_records"."variation_digest" = $2 LIMIT $3  [["blob_id", 144], ["variation_digest", "k9S9jJS87DbFgXD1sW9j5XkOr1c="], ["LIMIT", 1]]

I tried to eager load with the following but it doesn't seem to work:

Journey.includes(created_by_user: [profile_picture_attachment: { blob: :variant_records }])

Has anyone tried eager loading the tracked variant records to share your ideas?

aBadAssCowboy
  • 2,440
  • 2
  • 23
  • 38

1 Answers1

3

Turns out there is a pull request addressing exactly this. For anyone looking for a solution, please follow the merge request.

https://github.com/rails/rails/pull/37901

It eventually winds its way to a secondary PR, which allows eager loading the stored variants. It's now merged into future versions of Rails, here was the code they used to eager load variants:

https://github.com/rails/rails/pull/40842/files

wbharding
  • 4,213
  • 2
  • 30
  • 25
aBadAssCowboy
  • 2,440
  • 2
  • 23
  • 38