Ограничить запрос суммой атрибутов объектов в Rails и Postgresql - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть модель Lead, в которой есть предварительно вычисленный столбец с плавающей точкой, называемый sms_price.Я хочу разрешить пользователям отправлять текстовые сообщения этим лидерам и назначать бюджет для их кампаний (что-то похожее на то, что вы можете найти в объявлениях fb).

Мне нужна область действия, которая может ограничивать количествоведет по общей цене этих клиентов.Например, если пользователь определил общий бюджет в 200

  • id: 1 |sms_price: 0.5 |всего: 0,5
  • id: 2 |sms_price: 1.2 |всего: 1.7
  • id: 3 |sms_price: 0,9 |всего: 2,6
  • ...
  • id: 94 |цена смс: 0,8 |total_price: 199.4 <--- остановите запрос здесь </li>
  • 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 голосов
/ 27 ноября 2018

Проблема в том, что столбцы, вычисленные в предложении SELECT, не доступны предложению WHERE в том же операторе.Чтобы сделать то, что вы хотите, вам нужен подзапрос.

Вы можете сделать это и при этом остаться во вселенной Rails, используя метод ActiveRecord from.Техника хорошо проиллюстрирована в этом посте в блоге Hashrocket .

В вашем случае это может выглядеть примерно так (из-за сложности я бы использовал метод класса, а не область действия):

def self.limit_by_total_price(budget)
  subquery = select('leads.*, sum(leads.sms_price) over(order by leads.id) as total_price')
  from(subquery, :leads).where('total_price < ?', budget)
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...