После многих попыток я, наконец, нашел несколько ошибок, которые я совершил, и заархивировал поведение. Я хочу использовать такой код
services = Service.eager_load(payments: :manager)
services.reduce([]) do |acc, service|
service_rec = {
id: service[:id],
name: service[:name],
surgery: service[:surgery]
}
service.payments.each do |payment|
manager_name = payment.manager[:name]
value = payment[:value]
service_rec[manager_name] = value
end
acc.push(service_rec)
end
и SQL-запрос, который он выдает
SQL (0.2ms) SELECT "services"."id" AS t0_r0, "services"."code" AS t0_r1, "services"."name" AS t0_r2, "services"."surgery" AS t0_r3, "services"."enabled" AS t0_r4, "services"."created_at" AS t0_r5, "services"."updated_at" AS t0_r6, "payments"."id" AS t1_r0, "payments"."service_id" AS t1_r1, "payments"."manager_id" AS t1_r2, "payments"."value" AS t1_r3, "payments"."created_at" AS t1_r4, "payments"."updated_at" AS t1_r5, "managers"."id" AS t2_r0, "managers"."name" AS t2_r1, "managers"."enabled" AS t2_r2, "managers"."created_at" AS t2_r3, "managers"."updated_at" AS t2_r4 FROM "services" LEFT OUTER JOIN "payments" ON "payments"."service_id" = "services"."id" LEFT OUTER JOIN "managers" ON "managers"."id" = "payments"."manager_id"
Это интересночто использование includes
вместо eager_load
производит три запроса вместо
Service Load (0.1ms) SELECT "services".* FROM "services"
↳ app/services/payments_service.rb:6
Payment Load (0.1ms) SELECT "payments".* FROM "payments" WHERE "payments"."service_id" IN (?, ?, ?, ?, ?, ?, ?, ?) [["service_id", 1], ["service_id", 2], ["service_id", 3], ["service_id", 4], ["service_id", 5], ["service_id", 6], ["service_id", 7], ["service_id", 8]]
↳ app/services/payments_service.rb:6
Manager Load (0.1ms) SELECT "managers".* FROM "managers" WHERE "managers"."id" IN (?, ?, ?, ?) [["id", 1], ["id", 2], ["id", 3], ["id", 4]]
Также мы можем использовать Service.includes(payments: :manager).references(:payments, :managers)
и получить тот же запрос, что и eager_load
, но он длиннее для ввода))
Спасибо всем за участие!У кого-нибудь есть другое мнение по поводу eager_load
или предложений по оптимизации кода?