我有以下代码:
L.select('"l"."id", "ps"."name", "ps"."proposed_start", "ps"."proposed_finished", COUNT(*) as total, SUM(EXTRACT(EPOCH FROM ("l"."stop_at" - "l"."start_at"))) as duration, COUNT(CASE WHEN "l"."stop_at" IS NULL THEN 1 ELSE NULL END) as ongoing').
where(p_id: P.where.not(name: nil).select(:id)).
eager_load(:p).
group('"l"."id"')
注意:
P.where.not(name: nil)
只是一个随机条件,刺激它 将过滤掉不属于用户的P,但不是 完全与问题相关,因此我可以确认ActiveRecord会将其作为子查询运行。我也改名了 模型到L和P来混淆我的项目。我也知道总量 我的select中的函数不是SQL不可知的,我使用的是Postgresql。
但是,当我运行.to_sql
来检查SQL ActiveRecord会产生什么结果时,我发现我最终感到沮丧:
SELECT "l"."id",
"p"."name",
"p"."proposed_start",
"p"."proposed_finished",
Count(*) AS total,
Sum(Extract(epoch FROM ( "l"."stop_at" - "l"."start_at" ))) AS duration,
Count(CASE
WHEN "l"."stop_at" IS NULL THEN 1
ELSE NULL
END) AS ongoing,
"l"."id" AS t0_r0,
"l"."p_id" AS t0_r1,
"l"."user_id" AS t0_r2,
"l"."start_at" AS t0_r3,
"l"."stop_at" AS t0_r4,
"l"."comment" AS t0_r5,
"l"."created_at" AS t0_r6,
"l"."updated_at" AS t0_r7,
"l"."deleted_at" AS t0_r8,
"l"."deleted_by_id" AS t0_r9,
"p"."id" AS t1_r0,
"p"."name" AS t1_r1,
"p"."approved_by_id" AS t1_r2,
"p"."user_id" AS t1_r3,
"p"."proposed_start" AS t1_r4,
"p"."proposed_finished" AS t1_r5,
"p"."created_at" AS t1_r6,
"p"."updated_at" AS t1_r7,
"p"."p_status_id" AS t1_r8,
"p"."approved_at" AS t1_r9,
"p"."sub_unit_id" AS t1_r10,
"p"."details" AS t1_r11,
"p"."archived_at" AS t1_r12,
"p"."archived_by_id" AS t1_r13
FROM "l"
LEFT OUTER JOIN "p"
ON "p"."id" = "l"."p_id"
WHERE "l"."deleted_at" IS NULL
AND "l"."p_id" IN (SELECT "p"."id"
FROM "p"
WHERE ( "p"."name" IS NOT NULL ))
GROUP BY "l"."id"
正如您所看到的,ActiveRecord会自动选择已连接表的所有字段" p"以及我的具体选择。我怎么能阻止它呢?
答案 0 :(得分:1)
问题在于eager_load似乎不加选择地添加了相关模型的所有字段,忽略了您的选择'。如果您将其更改为INNER JOIN的连接而不是LEFT OUTER JOIN,则它会接受您的选择并按预期工作。