Rails 4按模型方法求和

时间:2014-08-12 22:04:32

标签: ruby-on-rails ruby activerecord ruby-on-rails-4.1 activerecord-relation

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

在控制器中,我的变量@users可能是UserActiveRecord::Relation users,我想将所有{{1}加起来} {s} @users s。

我的第一个倾向是:

goal_ytd

在两种情况下都抛出了弃用警告,因为在@users.sum(&:goal_ytd) 上使用sum将在Rails 4.1中消失。

所以,我把代码更改为:

ActiveRecord::Relation

然后扔了一个@users.to_a.sum(&:goal_ytd) ,因为在某种情况下NoMethodError@users分配,@users = User没有User方法。

使用to_a分配@users会引发弃用警告,因为@users = User.all也已弃用。

有没有办法让所有Relation#all成为一个数组?还有更好的方法吗?

4 个答案:

答案 0 :(得分:27)

On Rails 4.1

如果goal_ydt是users表中的列:

@users.sum(:goal_ydt)

如果goal_ydtUser类中的方法:

@users.to_a.sum(&:goal_ydt)

答案 1 :(得分:3)

我喜欢使用mapsum

的组合
@users.map(&:goal_ydt).sum

答案 2 :(得分:2)

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

@users.sum(:goal_ydt)  

编辑:

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

@users.scoped.sum(&:goal_ydt)

答案 3 :(得分:0)

这里的问题源于对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)

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