【问题标题】:Rails 3 scope, combine condition with aggregate (sum) results in errorRails 3范围,将条件与聚合(总和)结合会导致错误
【发布时间】:2012-07-11 18:18:06
【问题描述】:

我认为链接两个范围(Rails 3.2.5)是一个简单的问题。

我有一个名为Point 的模型,其中包含amounttransaction_date 等字段。用户在各种活动中获得一定数量的积分,在使用之前它们是“可用的”,这是作为交易的一部分发生的,此时 transaction_date 被更新,不再为空。

所以我有这样的范围:

scope :available, where("transaction_date IS NULL OR transaction_date = ''")

而且效果很好,可以返回正确的 Point 对象集合。所以我可以做

> Point.available
=> [#<Point id: 123, amount: 22, transaction_date: nil >][#<Point id: 456, amount: 33, transaction_date: nil >]

如果我想知道可用积分的总和,我可以这样做

> Point.available.sum("amount")
=> 55

但如果我尝试制作另一个类似的范围

scope :available, where("transaction_date IS NULL OR transaction_date = ''")
scope :total_available, available.sum("amount")

我得到了错误

NoMethodError: undefined method `default_scoped?' for 22:Fixnum

或者如果我将范围更改为 sum("amount").available 我会收到错误

NoMethodError: undefined method `available' for 55:Fixnum

我还可以通过添加:available 中定义的条件来使:total_available 范围工作,但这不是很干。

我在这里错过了什么?

【问题讨论】:

    标签: ruby-on-rails-3 aggregate arel


    【解决方案1】:

    表达式available.sum 立即得到评估,因此您的尝试等同于

    scope :total_available, 55
    

    或者

    scope :total_available, 55.available
    

    这显然是错误的。我个人会为此使用类方法

    def self.total_available
      available.sum(:amount)
    end
    

    我认为作用域是一个作用域集合:作用域是数字对我来说没有意义 - 一方面,它们是你不能将其他作用域链接到的作用域

    【讨论】:

    • 感谢@Frederick Chung -- 感谢您对错误的解释,这有助于我理解失败。我还认为您的解决方案是实用的,并且您对其使用的推理是合乎逻辑的。但是,范围在 AREL 和documented here 中实现,并显示了一种类似于我的案例——链接用作额外的细化。也许我的问题应该是“Rails 有正确的方法吗?”使用具有聚合的范围,例如 sum?
    • 我可以看到在范围内运行计算的示例,但没有定义作为计算的范围
    • 是的,显然它们与常规范围有点不同。无论如何,您的解决方案几乎与范围相同。
    猜你喜欢
    • 1970-01-01
    • 2021-04-11
    • 1970-01-01
    • 1970-01-01
    • 2013-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多