2017-06-21 17 views
0

I次のコードを持っている:ActiveRecordを自動的に特別に選択されたオーバーライドフィールド

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のユーザーに属していないようフィルタリングされますPRODで、単にランダムな状態でありますしかし、その という質問に関連するので、ActiveRecordがサブクエリとして実行することを確認できました。また、 モデルの名前をLとPに変更して、プロジェクトを難読化しました。また、私の選択で集計 関数がSQLに依存していないことを知っている、私はPostgreSQLを使用しています。

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のは、自動的にすべてを選択している:私は結果のSQL ActiveRecordのは、私は私が終わる私の落胆に発見生み出すものを検査する.to_sqlを実行したときただし、

私の特定の選択と同様に、結合されたテーブル "p"のフィールド。それをやめないようにするにはどうすればいいですか?

+0

なぜRailsが複数の列を選択すると問題になるのですか?なぜ 'join 'の代わりに' eager_load'を使うのですか? – spickermann

+0

集計関数またはグループ化基準に含まれていないため、SQLは実行されません。 Eager_loadは私にLEFT OUTER JOINを与え、ジョインはINNER JOINを与えます。 – Ash

答えて

1

問題は、関連するモデルのすべてのフィールドを無差別に追加して、「選択」を無視しているように見えるeager_loadです。 LEFT OUTER JOINの代わりにINNER JOINのジョインに変更すると、選択したものが受け入れられ、意図したとおりに動作します。

関連する問題