使用select()的Rails ActiveRecord / Arel查询聚合列
我有两个带连接表的基本模型。 我添加了一个范围来计算关系中的计数,并将其作为属性/ psuedo-column公开。 一切正常,但我现在想查询列的子集并包含count列,但我不知道如何引用它。
tldr; 如何在我的Arel查询中包含聚合(如计数),同时还要选择列的子集?
模型是Employer
和Employee
,通过Job
加入。 以下是Employer
的相关代码:
class Employer do left_outer_joins(:employees). group("employers.id"). select("employers.*, count(employees.*) as employees_count") end end
这允许我向雇主加载计数:
employers = Employer.include_counts.where(id: 1)
然后引用计数:
count = employers[0].employees_count
我正在我的控制器中加载记录,然后呈现它。 不过,我不想渲染超出我需要的字段。 在添加计数之前,我可以这样做:
employers = Employer.where(id: 1).select(:id, :name)
当我添加我的include_counts
范围时,它基本上忽略了select()
。 它不会失败,但它最终包括所有列,因为我的范围中的这一行:
select("employers.*, count(employees.*) as employees_count")
如果我从范围中删除employers.*
那么我的结果中没有任何列,无论是否有select()
子句。
我试过这个:
employers = Employer.include_counts.where(id: 1).select(:id, :name, :employee_counts)
…但是会产生以下SQL:
SELECT employers.*, count(employees.*) as employees_count, id, name, employees_count FROM
…和SQL错误,因为列employees_count
不存在,并且id
和name
不明确。
唯一有用的是:
employers = Employer.include_counts.where(id: 1).select("employers.id, employers.name, count(employees.*) as employees_count")
…但实际上由于范围条款,实际上选择了employers
所有列。
如果我可以避免它,我也不希望原始SQL泄漏到我的控制器中。 使用Rails / Arel是否有更惯用的方法?
如果我找不到另一种方法来进行查询,我可能会在模型中创建另一个范围或自定义查找程序,以便控制器代码更清晰。 我也愿意接受这样做的建议,但是我想知道是否有一种简单的方法来引用像这样的计算聚合列,就像它们是任何其他列一样。