Ответ от ursus должен быть правильным, но я хотел бы предоставить некоторую дополнительную информацию о коде, который вы написали.
select
, который вы делаете в своем методе self.range
, - это метод Enumerable или Array.который работает с запросом после его выполнения, и это одна из причин, по которой вы видите столько запросов. Enumerable # select
A select
в ActiveRecord фактически выбирает, какие столбцы вы хотите получить:
Person.select(:id, :name) # only returns the columns id & name
Вы хотите выполнить where
:
class Payment < ApplicationRecord
belongs_to :person
def self.in_range(range)
where('date between ? and ?', range.begin, range.end)
end
end
Это дает вам возможность делать:
Person.first.sales_volume(Time.zone.today - 30.days..Time.zone.today)
Это работает только на одного человека (что все еще может быть полезно).
Если вы хотите выполнить этот тип запроса к коллекции, вам понадобится что-то более сложное, как указывал Урсус.
people =
Person.
select('people.*, SUM(payments.amount) AS sales_volume').
joins(:payments).
merge(
Payment.
in_range(
(Time.zone.today - 30.days)..Time.zone.today)
).
group('people.id')
people.first.sales_amount # prints sales amount
Вы можете преобразовать все это в свой with_sales_volume
метод, как заметил Урсус.