代码之家  ›  专栏  ›  技术社区  ›  hadees

命名的\u scope+average导致在postgresql上运行的sql查询中多次指定表

  •  1
  • hadees  · 技术社区  · 15 年前

      named_scope :gender, lambda { |gender| { :joins => {:survey_session => :profile }, :conditions => { :survey_sessions => { :profiles => { :gender => gender } } } } }
    

    当我叫它的时候一切都很好。

    我也有一个我称之为。。。

    Answer.average(:rating, :include => {:survey_session => :profile}, :group => "profiles.career")
    

    如果我这样称呼的话,也可以。

    但是如果我这么说的话。。。

    Answer.gender('m').average(:rating, :include => {:survey_session => :profile}, :group => "profiles.career")
    

    我得到。。。

    ActiveRecord::StatementInvalid:PGError:错误:表名“profiles”指定了多次 :选择avg(“answers”.rating)作为avg\u rating,职业简介作为profiles\u career FROM“answers”LEFT OUTER JOIN“survey\u sessions”survey\u sessions\u answers ON“survey\u sessions\u answers”。id=“answers”。survey\u session\u id LEFT OUTER JOIN“profiles”profiles。id=“survey\u sessions\u answers”。profiles\u id INNER JOIN“survey\u sessions”ON“survey\u sessions”。id=“answers”。survey加入“profiles”上的“profiles”。id=“survey\u sessions”。profile\u id WHERE(“profiles”。“gender”=E'm')分组方式职业简介

    这是一个有点难读,但说我包括表配置文件两次。

    如果我只是从average中删除include,它可以工作,但实际上并不实用,因为average实际上是在传递作用域的方法中调用的。因此,有时性别或平均水平可能会被叫出对方,如果其中任何一个是失踪的个人资料,包括它不会工作。

    因此,要么我需要知道如何修复Rails中的这个明显的bug,要么我需要找到一种方法来知道ActiveRecord::NamedScope::Scope对象应用了哪些作用域,这样我就可以检查是否应用了这些作用域,如果没有,则添加include for average。

    1 回复  |  直到 15 年前
        1
  •  2
  •   araqnid    15 年前

    看起来ActiveRecord正在生成一些错误的SQL:

    SELECT avg("answers".rating) AS avg_rating,
           profiles.career AS profiles_career
    FROM "answers"
         LEFT OUTER JOIN "survey_sessions" survey_sessions_answers
                        ON "survey_sessions_answers".id = "answers".survey_session_id
         LEFT OUTER JOIN "profiles"
                         ON "profiles".id = "survey_sessions_answers".profile_id
         INNER JOIN "survey_sessions"
                    ON "survey_sessions".id = "answers".survey_session_id
         INNER JOIN "profiles"
                    ON "profiles".id = "survey_sessions".profile_id
    WHERE ("profiles"."gender" = E'm')
    GROUP BY profiles.career
    

    假设它生成了左连接作为获取投影属性的一部分,而生成了内部连接作为获取条件的一部分:如果它为这些表分配了别名,这不会是无效的(只是效率低下),但是它不会。有没有办法从应用程序中指定别名?