Если я использую eager_load
для извлечения нужной ассоциации в одном запросе, я получаю слишком много столбцов:
scope = Product.eager_load(:account).to_a
scope.last.account.name
Затем я получаю запрос, который выглядит следующим образом:
SQL (3.3ms) SELECT "products"."id" AS t0_r0, "products"."account_id" AS t0_r1, "products"."notes" AS t0_r2, "products"."created_at" AS t0_r3, "products"."updated_at" AS t0_r4, "products"."rep_id" AS t0_r5, "products"."senior_rep_id" AS t0_r6, "products"."name_id" AS t0_r7...
Моя цель - просто получить нужные столбцы, как я ожидал, позвонив по номеру .select("intakes.id, intakes.account_id, accounts.id, accounts.name")
. Однако, если я добавлю это к моему запросу, он просто добавляет эту строку вперед и в основном игнорирует ее:
SQL (3.3ms) SELECT products.id, products.account_id, accounts.id, accounts.name, "products"."id" AS t0_r0, "products"."account_id" AS t0_r1, "products"."notes" AS t0_r2, "products"."created_at" AS t0_r3, "products"."updated_at" AS t0_r4, "products"."rep_id" AS t0_r5, "products"."senior_rep_id" AS t0_r6, "products"."name_id" AS t0_r7...
Так что теперь мой запрос стал еще длиннее, но я не получил никакой выгоды. Я также могу попробовать с left_joins
:
scope = Product.left_joins(:account).select("products.id, products.account_id, accounts.id, accounts.name").to_a
Это даст мне N + 1 запросов, где выбор игнорируется для ассоциаций:
Products Load (0.9ms) SELECT products.id, products.account_id, accounts.id, accounts.name FROM "products" LEFT OUTER JOIN "accounts" ON "accounts"."id" = "products"."account_id"
Account Load (0.2ms) SELECT "accounts".* FROM "accounts" WHERE "accounts"."id" = $1 LIMIT $2 [["id", 16], ["LIMIT", 1]]
Однако я могу избежать N +1, если я узнаю выбранные столбцы DID go где-нибудь, в этом accounts.name
, сопоставленном с name
в Продукте:
scope.last.attributes["name"]
Технически это дает мне информацию, которую я хочу получить в одном запросе, но при создании реального запроса со многими ассоциациями попытка переименовать и переназначить эти данные во множество пользовательских имен внезапно заставляет задуматься, почему я вообще использую ActiveModel. Есть ли еще «Rails Way» для этого, где scope.last.account.name
будет по-прежнему иметь значение, установленное так, как если бы я использовал eager_load
?