Rails 4 模型方法求和

Posted

技术标签:

【中文标题】Rails 4 模型方法求和【英文标题】:Rails 4 Sum by Model Method 【发布时间】:2014-10-06 03:28:37 【问题描述】:

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

在控制器中,我有一个变量@users,它可能是UserusersActiveRecord::Relation,我想总结所有@usersgoal_ytds。

我的第一个想法是:

@users.sum(&:goal_ytd)

这在这两种情况下都引发了弃用警告,因为在 Rails 4.1 中将不再使用 sumActiveRecord::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_ydtUser 类中的方法:

@users.to_a.sum(&:goal_ydt)

【讨论】:

如何将参数传递给方法? @users.to_a.sum |u| u.goal_ytd(parameter) 【参考方案2】:

我喜欢结合使用mapsum

@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 模型方法求和的主要内容,如果未能解决你的问题,请参考以下文章

EXCEL中对1个单元格中多个数字求和

EXCEL条件求和怎么用??

python数组求和

数组求和方法汇总

二维索引和求和的numpy数组

对数组元素求和