3

I'd like to select a collection of ActiveRecord objects and their belongs_to related object with a single query done. I.e. after calling

products = Product.joins(:image).limit(10)

and while iterating over products, I want that product.image didn't cause another query to the DB, but it had that image attribute already populated with Image instance cached from previous query instead.

How do I construct params for select, so that it selected all attributes needed to populate related objects? Or maybe I am looking in a wrong direction and there's some other way to reduce these unnecessary queries on each iteration:

Image Load (1.0ms)  SELECT "images".* FROM "images" WHERE "images"."id" = 270783 LIMIT 1
Image Load (1.2ms)  SELECT "images".* FROM "images" WHERE "images"."id" = 121344 LIMIT 1
Image Load (1.2ms)  SELECT "images".* FROM "images" WHERE "images"."id" = 196239 LIMIT 1
Image Load (1.2ms)  SELECT "images".* FROM "images" WHERE "images"."id" = 91194 LIMIT 1 
Image Load (1.2ms)  SELECT "images".* FROM "images" WHERE "images"."id" = 116278 LIMIT 1
Image Load (1.2ms)  SELECT "images".* FROM "images" WHERE "images"."id" = 117207 LIMIT 1
Image Load (0.8ms)  SELECT "images".* FROM "images" WHERE "images"."id" = 244471 LIMIT 1
Image Load (0.8ms)  SELECT "images".* FROM "images" WHERE "images"."id" = 239287 LIMIT 1
Image Load (0.8ms)  SELECT "images".* FROM "images" WHERE "images"."id" = 15124 LIMIT 1 
Image Load (1.2ms)  SELECT "images".* FROM "images" WHERE "images"."id" = 186670 LIMIT 1

1 Answer 1

2

What you want is called "eager loading". And all you have to do is change your .joins(:image) to .includes(:image) to get eager loading.

products = Product.includes(:image).limit(10)

See also the Rails Guide on Eager Loading.

1
  • Perfect! Exactly what I needed. Well, almost, because I thought it can be done with one query not two, but that's not important.
    – Hnatt
    Commented May 24, 2014 at 16:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.