Rails 4按模型方法求和

在我的应用程序中,我有一个User模型,带有goal_ytd方法,它执行一些计算。

在一个控制器中,我有一个变量@users ,可能是UserActiveRecord::Relation goal_ytdusers ,我想总结所有@usersgoal_ytd

我的第一个倾向是:

 @users.sum(&:goal_ytd) 

在两种情况下都抛出了弃用警告,因为在Active 4.1中使用对ActiveRecord::Relation sum消失了。

所以,我将代码更改为:

 @users.to_a.sum(&:goal_ytd) 

然后抛出一个NoMethodError因为在某种情况下, NoMethodError@users = User分配,而User没有to_a方法。

使用@users = User.all分配@users会抛出弃用警告,因为Relation#all也已弃用。

有没有办法让所有Users成为一个数组? 有没有更好的办法?

在Rails 4.1

如果goal_ydt是users表中的列:

 @users.sum(:goal_ydt) 

如果goal_ydtUser类中的方法:

 @users.to_a.sum(&:goal_ydt) 

你不应该在这里使用可枚举的方法。 使用在ActiveRecord :: Relation上定义的sum ,并将symbol作为参数。 主要区别在于它将在您的数据库中执行SUM查询,因此它比从db中提取所有记录要快得多。 此外,如果您的任何记录对于给定字段具有空值,则可枚举的sum将抛出错误,而ActiveRecord的则不会。 简而言之:

 @users.sum(:goal_ydt) 

编辑:

但是由于goal_ydt不是一个字段而是一个方法,你别无选择,只能遍历模型。 我通常这样做的方法是使用scoped方法:

 @users.scoped.sum(&:goal_ydt) 

我喜欢使用mapsum的组合

 @users.map(&:goal_ydt).sum 

这里的问题根源于对Relation#all弃用的基本误解。 虽然不推荐使用Relation#all ,但Model#all不是。 因此:

 @users = User.all 

仍然完全有效,同时:

 @users = User.where(first_name: "Mike").all 

已弃用。

所以最终的解决方案看起来像:

 @users = User.all unless current_user.admin? @users = @users.where(company_id: current_user.company_id) end @users.to_a.sum(&:goal_ytd) 

一个新的问题是:我如何总结所有用户目标,最好是在一行中,而不是将它们全部加载到内存中? 我想那是另一天。