ActiveRecord会自动覆盖特定选定的字段

时间:2017-06-21 04:26:45

标签: ruby-on-rails ruby postgresql activerecord ruby-on-rails-5

我有以下代码:

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"以及我的具体选择。我怎么能阻止它呢?

1 个答案:

答案 0 :(得分:1)

问题在于eager_load似乎不加选择地添加了相关模型的所有字段,忽略了您的选择'。如果您将其更改为INNER JOIN的连接而不是LEFT OUTER JOIN,则它会接受您的选择并按预期工作。