То, что вы хотите сделать, это выбрать счетчик, сгруппированный по дням. Как именно этого добиться, зависит от того, какая база данных используется.
Postgres:
date_trunc('day', created_at)
MySQL:
date_format(created_at, '%Y-%m-%d')
Для других БД проверьте документацию для функций даты.
В целом требуемый запрос выглядит примерно так:
SELECT
count(*) AS count,
date_trunc('day', created_at) AS day
FROM "enrollments"
WHERE (created_at >= ?) -- one month ago
GROUP BY day
ORDER BY day
Мы можем записать это в ActiveRecord как:
Enrollment.select("count(*) AS count, to_char(created_at, 'YYYY-MM-DD') AS day")
.group("day")
.order("day")
.where(created_at: (1.month.ago..Time.current))
Но это дает ActiveRecord :: Relation of records, что не очень полезно. Чтобы получить необработанные значения запроса, мы хотим использовать #select_all
.
sql = Enrollment.select("count(*) AS count, date_trunc('day', created_at) AS day")
.group("day")
.order("day")
.where("created_at >= ?", 1.month.ago)
.to_sql
results = Enrollment.connection.select_all(sql)
Когда вы конвертируете результаты в массив, вы получите массив хэшей:
[{"count"=>10, "day"=>"2018-10-20 00:00:00"}, {"count"=>10, "day"=>"2018-10-21 00:00:00"}, {"count"=>10, "day"=>"2018-10-22 00:00:00"}, {"count"=>10, "day"=>"2018-10-23 00:00:00"}, {"count"=>10, "day"=>"2018-10-24 00:00:00"}, {"count"=>10, "day"=>"2018-10-25 00:00:00"}, ...]
Вы можете извлечь счет, сопоставив массив:
results.map {|r| r["count"] }
Если вы хотите получить результаты только для одного (или нескольких) ClassStandards, просто добавьте дополнительное условие к предложению where:
sql = Enrollment.select("count(*) AS count, date_trunc('day', created_at) AS day")
.group("day")
.order("day")
.where("created_at >= ?", 1.month.ago)
.where(class_standard: @class_standard)
.to_sql
Или вы называете это вне ассоциации:
sql = @class_standard.enrollments
.select("count(*) AS count, date_trunc('day', created_at) AS day")
.group("day")
.order("day")
.where("created_at >= ?", 1.month.ago)
.to_sql