通过Rails和Postgresql中的对象属性总和来限制查询

时间:2018-11-27 15:57:39

标签: ruby-on-rails postgresql activerecord ruby-on-rails-5

我有一个Lead模型,该模型具有一个预先计算的称为“ sms_price”的浮点列。我想允许用户向这些潜在客户发送短信,并为他们的广告系列分配预算(类似于您在fb广告中可以找到的预算)。

我需要一个可以通过潜在顾客的总价格来限制潜在顾客的数量的范围。因此,例如,如果用户定义的总预算为200

  • id:1 | sms_price:0.5 |总计价格:0.5
  • id:2 | sms_price:1.2 | total_price:1.7
  • id:3 | sms_price:0.9 | total_price:2.6
  • ...
  • id:94 | sms_price:0.8 | total_price:199.4 <---在此处停止查询
  • id:95 | sms_price:0.7 | total_price:200.1

所以我需要在我的范围内做两件事:

  1. 递归计算总价格
  2. 仅获取总价低于所需预算的销售线索

到目前为止,我仅使用以下范围完成了第一个任务(递归计算总价格):

scope :limit_by_total_price, ->{select('"leads".*, sum(sms_price) OVER(ORDER BY id) AS total_price')}

这有效,如果我Lead.limit_by_total_price.last.total_price,我得到38039.7499999615

现在,我需要的是一种仅检索总价格低于预算的销售线索的方法:

scope :limit_by_total_price, ->(budget){select('"leads".*, sum(sms_price) OVER(ORDER BY id) AS total_price').where('total_price < ?', budget)}

但是它不能识别total_price属性:

ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR:  column "total_price" does not exist

为什么它在单个对象中而不在范围中识别total_price属性?

1 个答案:

答案 0 :(得分:2)

问题在于,在SELECT子句中计算出的列不可用于同一语句中的WHERE子句。要执行您想要的操作,您需要一个子查询。

您可以执行此操作,但仍可以使用ActiveRecord的from方法保留在Rails领域中。该技术在this Hashrocket blog post中得到了很好的说明。

在您的情况下,它可能看起来像这样(由于复杂性,我将使用类方法而不是范围):

core