【问题标题】:sum(&:x) not working any moresum(&:x) 不再工作了
【发布时间】:2014-08-21 06:40:13
【问题描述】:

我在我的 Rails 应用程序 (4.1.2) 中使用 payments.sum(&:price)。 由于我从 Ruby 1.9.3 更新到 2.1.2,我收到以下错误:

wrong number of arguments (1 for 2..3)

这些变体有效:

payments.map(&:price).sum
payments.to_a.sum(&:price)

我必须重写我的代码还是我错过了什么? 谢谢!

【问题讨论】:

  • 什么是payments? Rails 有两种不同的sum 方法:Enumerable#sumActiveRecord::Relation#sum。第一个占用一个块(这就是&to_proc 运算符起作用的原因);第二个没有。无论如何,我很确定将 Ruby 从 1.9.3 升级到 2.1 是一个红鲱鱼。 & 行为在这些版本之间没有改变。

标签: ruby ruby-on-rails-4 sum


【解决方案1】:

来自documentation

sum(*args)

计算给定列的值的总和。返回值 具有相同数据类型的列,如果没有行,则为 0。看 计算带有选项的示例。

Person.sum(:age) # => 4562

看来你的代码应该没有&:

payments.sum(:price)

【讨论】:

  • 这似乎只适用于列名 - 任何快速简便的方法可以使用 sum used to work 这样的方法来做到这一点?
  • @Sean 如果你不使用rails,你可以简单地使用经典的inject,像这样:payments.map(&:price).inject(:+)
【解决方案2】:

如果支付是一个 ActiveRecord 关联,您可以改用ActiveRecord::Calculations sum 方法:

payments.sum(:price)

【讨论】:

    【解决方案3】:

    sum 是 Rails 定义的 Enumerable 模块上的方法,而不是 Ruby。升级 ruby​​ 版本应该没什么区别:

    http://api.rubyonrails.org/classes/Enumerable.html#method-i-sum

    但是,如果您使用它对 ActiveRecord 上的列求和,我建议在 ActiveRecord::Relation 上使用 sum 方法。正如其他答案所建议的那样,您可以通过删除 & 来做到这一点。

    http://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-sum

    不同之处在于前者从数据库中获取所有记录,创建对象,对它们调用price 方法并对结果求和。后者使用 SUM 创建 SQL 语句,这对于性能来说要好得多。

    【讨论】:

      【解决方案4】:

      如果您在 Rails 4.0 中运行此程序,您将收到以下弃用警告:

      弃用警告:使用块调用#sum 已被弃用,并将 在 Rails 4.1 中删除。如果要执行总和计算 元素数组,使用'to_a.sum(&block)'。

      这是指 Relation#sum 方法,它以前在 Rails 3.2 中在给定块时工作。

      正如其他人已经回答的那样,如果 price 是数据库列,您需要使用 payments.sum(:price),或者如果 price 是实例方法,则使用 payments.to_a.sum(&:price)

      【讨论】:

        猜你喜欢
        • 2022-08-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-18
        相关资源
        最近更新 更多