在我的应用中,我有一个User
模型,使用goal_ytd
方法执行一些计算。
在控制器中,我的变量@users
可能是User
或ActiveRecord::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
成为一个数组?还有更好的方法吗?
答案 0 :(得分:27)
On Rails 4.1
如果goal_ydt
是users表中的列:
@users.sum(:goal_ydt)
如果goal_ydt
是User
类中的方法:
@users.to_a.sum(&:goal_ydt)
答案 1 :(得分:3)
我喜欢使用map
和sum
@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)
一个新的问题是:如何将所有用户目标相加,最好是在一行中,而不是将它们全部加载到内存中?我想那是另一天。