Rails 4 模型方法求和
Posted
技术标签:
【中文标题】Rails 4 模型方法求和【英文标题】:Rails 4 Sum by Model Method 【发布时间】:2014-10-06 03:28:37 【问题描述】:在我的应用程序中,我有一个 User
模型,带有一个 goal_ytd
方法,它执行一些计算。
在控制器中,我有一个变量@users
,它可能是User
或users
的ActiveRecord::Relation
,我想总结所有@users
的goal_ytd
s。
我的第一个想法是:
@users.sum(&:goal_ytd)
这在这两种情况下都引发了弃用警告,因为在 Rails 4.1 中将不再使用 sum
在 ActiveRecord::Relation
上。
所以,我将代码更改为:
@users.to_a.sum(&:goal_ytd)
然后抛出一个NoMethodError
,因为在某种情况下,@users
是由@users = User
分配的,而User
没有to_a
方法。
使用@users = User.all
分配@users
会引发弃用警告,因为Relation#all
也已弃用。
有没有办法将所有Users
作为一个数组?有没有更好的办法?
【问题讨论】:
你试过@users.sum(:goal_ydt)
吗?
【参考方案1】:
在 Rails 4.1 上
如果goal_ydt
是用户表中的一列:
@users.sum(:goal_ydt)
如果goal_ydt
是User
类中的方法:
@users.to_a.sum(&:goal_ydt)
【讨论】:
如何将参数传递给方法?@users.to_a.sum |u| u.goal_ytd(parameter)
【参考方案2】:
我喜欢结合使用map
和sum
@users.map(&:goal_ydt).sum
【讨论】:
@Fran Martinez,您能否向我解释一下为什么在使用group_by
时需要Model.map(&:goal_ydt).sum
。为什么在使用 .group(:id)
时,rails 不能进行数据库求和(而不是哈希求和)?就像标准的Model.sum(:price)
?【参考方案3】:
你不应该在这里使用可枚举的方法。使用在 ActiveRecord::Relation 上定义的sum
,并将符号作为参数。主要区别在于它将在您的数据库中执行SUM
查询,因此它比从数据库中提取所有记录要快得多。此外,如果您的任何记录对于给定字段具有空白值,则可枚举的sum
将引发错误,而 ActiveRecord 的则不会。简而言之:
@users.sum(:goal_ydt)
编辑:
但是,由于goal_ydt
不是字段而是方法,因此您别无选择,只能遍历模型。我通常这样做的方式是使用scoped
方法:
@users.scoped.sum(&:goal_ydt)
【讨论】:
这里的问题是goal_ytd
是用户的方法,而不是属性。【参考方案4】:
这里的问题源于对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)
一个新问题是:我如何在不将所有用户目标全部加载到内存的情况下,将所有用户目标汇总在一起,最好放在一行中?我想那是另一天。
【讨论】:
以上是关于Rails 4 模型方法求和的主要内容,如果未能解决你的问题,请参考以下文章