Ruby on rails 在聚合函数之前对ActiveRecord对象执行行操作

Ruby on rails 在聚合函数之前对ActiveRecord对象执行行操作,ruby-on-rails,ruby,activerecord,Ruby On Rails,Ruby,Activerecord,我试图根据模型中的第二个变量计算模型中某个变量的加权平均值,但我很难通过ActiveRecord找到一种方法来实现 class Employer < ActiveRecord::Base attr_accessible :name, :number_of_employees, :average_age def self.wt_avg_age #return sum(number_of_employee * average_age)/sum(number_of_employ

我试图根据模型中的第二个变量计算模型中某个变量的加权平均值,但我很难通过ActiveRecord找到一种方法来实现

class Employer < ActiveRecord::Base
  attr_accessible :name, :number_of_employees, :average_age

  def self.wt_avg_age
    #return sum(number_of_employee * average_age)/sum(number_of_employees)
  end
end 

我可以在ActiveRecord关系上以一种雄辩的方式执行类似的操作吗?也就是说,不需要拆下单独的数组并遍历每个记录来获取分子?我尝试过使用.select、.pull和sum的不同组合,但没有任何运气。让ActiveRecord对象执行sumproduct时遇到问题。

试试看,也许它可以工作:

def self.wt_avg_age
  a = Employer.sum("number_of_employee * average_age")
  b = Employer.sum('number_of_employees')
  a/b
end

您应该能够执行以下操作:

Employer.select("name, (SUM(number_of_employees*average_age)/SUM(number_of_employees)) as sum").group(:name)
这会将雇主实例返回给您,但它们只具有.name和.sum属性。这将运行您想要的确切SQL查询。

看起来ActiveRecord::CalculationSum需要一个块:

# File activerecord/lib/active_record/relation/calculations.rb, line 92
def sum(*args)
  if block_given?
    self.to_a.sum(*args) {|*block_args| yield(*block_args)}
  else
    calculate(:sum, *args)
  end
end
也看到

因此,您可以尝试:

def self.wt_avg_age
  numerator = self.all.sum { |e| e.number_of_employee * e.average_age }
  denominator = self.sum :number_of_employees
  return numerator / denominator
end

为什么要使用简单sql查询可以使用的对象模型?为作业使用正确的工具。id是唯一的。如果你按id分组,你不会真的完成任何事情——这相当于从雇主那里选择雇员人数*平均年龄/雇员人数。是否还有其他可能分组的内容,或者这应该是单行结果?我编了一个示例,所以忽略了这一点。我现在按名字分组。我应该为每个名字返回一条记录。我对Rails有点陌生,所以我只是想知道我是否忽略了一些不用SQL就能实现这一点的构造。我更喜欢在任何地方使用SQL,但我正在学习并尝试应用ActiveRecord。这就是我一直在寻找的。谢谢再想一想,这并没有给我按名称分组的选项,所以它不太有效。小心,这将在ruby land中进行计算,而不是通过SQL
def self.wt_avg_age
  numerator = self.all.sum { |e| e.number_of_employee * e.average_age }
  denominator = self.sum :number_of_employees
  return numerator / denominator
end