Sql 创建连接到子查询的Rails 3作用域

Sql 创建连接到子查询的Rails 3作用域,sql,ruby-on-rails,activerecord,Sql,Ruby On Rails,Activerecord,首先,我是Ruby/Rails的新手,如果这个问题是基本的,我很抱歉 我有一个DB(除其他外)如下所示: organizations { id, name, current_survey_id } surveys { id, organization_id } responses { id, survey_id, question_response_integer } select * from organizations select o.id, o.name, cs.average_re

首先,我是Ruby/Rails的新手,如果这个问题是基本的,我很抱歉

我有一个DB(除其他外)如下所示:

organizations { id, name, current_survey_id }
surveys { id, organization_id }
responses { id, survey_id, question_response_integer }
select * from organizations
select o.id, o.name, cs.average_responses
from organizations o join
(select r.id, avg(r.question_response_integer) as average_responses 
     from responses r 
     group by r.id) cs on cs.id = o.current_survey_id
current_survey_average: lambda do |scope, sort_direction|
  average_answers = Responses.
     select("survey_id, avg(question_response_integer) as average_responses").
     group("survey_id")
  scope.joins(average_answers).order("average_responses #{sort_direction}")
end
我试图创建一个scope方法,将当前调查答案的平均值添加到传入的组织关系中。换句话说,传递到方法中的作用域将生成大致如下所示的SQL:

organizations { id, name, current_survey_id }
surveys { id, organization_id }
responses { id, survey_id, question_response_integer }
select * from organizations
select o.id, o.name, cs.average_responses
from organizations o join
(select r.id, avg(r.question_response_integer) as average_responses 
     from responses r 
     group by r.id) cs on cs.id = o.current_survey_id
current_survey_average: lambda do |scope, sort_direction|
  average_answers = Responses.
     select("survey_id, avg(question_response_integer) as average_responses").
     group("survey_id")
  scope.joins(average_answers).order("average_responses #{sort_direction}")
end
我希望作用域在被lambda处理后生成如下所示的SQL:

organizations { id, name, current_survey_id }
surveys { id, organization_id }
responses { id, survey_id, question_response_integer }
select * from organizations
select o.id, o.name, cs.average_responses
from organizations o join
(select r.id, avg(r.question_response_integer) as average_responses 
     from responses r 
     group by r.id) cs on cs.id = o.current_survey_id
current_survey_average: lambda do |scope, sort_direction|
  average_answers = Responses.
     select("survey_id, avg(question_response_integer) as average_responses").
     group("survey_id")
  scope.joins(average_answers).order("average_responses #{sort_direction}")
end
我得到的最好的东西是这样的:

organizations { id, name, current_survey_id }
surveys { id, organization_id }
responses { id, survey_id, question_response_integer }
select * from organizations
select o.id, o.name, cs.average_responses
from organizations o join
(select r.id, avg(r.question_response_integer) as average_responses 
     from responses r 
     group by r.id) cs on cs.id = o.current_survey_id
current_survey_average: lambda do |scope, sort_direction|
  average_answers = Responses.
     select("survey_id, avg(question_response_integer) as average_responses").
     group("survey_id")
  scope.joins(average_answers).order("average_responses #{sort_direction}")
end
这基本上只是一个暗中操作——除其他事项外,它没有指定如何将作用域连接到
average\u answers
——但我还没有找到任何关于如何进行这种连接的文档,我已经没有什么可以尝试的了

有什么建议吗

编辑:谢谢肖恩·希尔的回答。为了记录在案,以下是我最终使用的代码:

current_survey_average: lambda do |scope, sort_direction|
  scope_table = scope.arel.froms.first.name
  query = <<-QUERY
    inner join (
     select r.survey_id, avg(r.question_response_integer) as average_responses
      from responses r
      group by r.survey_id
    ) cs
    on cs.survey_id = #{scope_table}.current_survey_id
  QUERY
  scope.
    joins(query).
    order("cs.average_responses #{sort_direction}")
end
当前调查平均值:lambda do范围、排序方向|
scope\u table=scope.arel.froms.first.name

query=我还不能测试这个,但是我认为下面的方法可以正常工作,或者稍微调整一下

class Response < ActiveRecord::Base
  scope :averaged, -> { select('r.id, avg(r.question_response_integer) as average_responses').group('r.id') }

  scope :current_survey_average, ->(incoming_scope, sort_direction) do
    scope_table = incoming_scope.arel.froms.first.name
    query = <<-QUERY
      INNER JOIN ( #{Arel.sql(averaged.to_sql)} ) cs
      ON cs.id = #{scope_table}.current_survey_id
    QUERY

    incoming_scope.joins(query).order("average_responses #{sort_direction}")
  end
end
类响应{select('r.id,avg(r.question\u response\u integer)作为平均\u responses')。group('r.id')}
范围:当前调查平均值,->(传入范围、排序方向)do
scope\u table=传入的\u scope.arel.froms.first.name

query=我还不能测试这个,但是我认为下面的方法可以正常工作,或者稍微调整一下

class Response < ActiveRecord::Base
  scope :averaged, -> { select('r.id, avg(r.question_response_integer) as average_responses').group('r.id') }

  scope :current_survey_average, ->(incoming_scope, sort_direction) do
    scope_table = incoming_scope.arel.froms.first.name
    query = <<-QUERY
      INNER JOIN ( #{Arel.sql(averaged.to_sql)} ) cs
      ON cs.id = #{scope_table}.current_survey_id
    QUERY

    incoming_scope.joins(query).order("average_responses #{sort_direction}")
  end
end
类响应{select('r.id,avg(r.question\u response\u integer)作为平均\u responses')。group('r.id')}
范围:当前调查平均值,->(传入范围、排序方向)do
scope\u table=传入的\u scope.arel.froms.first.name

非常感谢,这就是答案。我在上面发布了我的修改版本:非常感谢。非常感谢,这就是答案。我在上面发布了我的修改版本:非常感谢。