如果没有找到记录,如何用padding将过去7天的记录提取到0?

时间:2016-03-27 16:36:25

标签: ruby-on-rails activerecord

我正在尝试从过去7天获取记录(可能会更改为支持月份和年份)来填充图表,我需要填写没有找到记录的日子。我首先尝试分组但发现无法填充数据,所以我想出了这个:

today = Date.today

array_data = (today - 6.days..today).map do |day|  
  total_time = @project.time_entries.where(created_at: (day.beginning_of_day..day.end_of_day)).map(&:duration_hours).sum

  { day.strftime("%a %d %b") => total_time }
end

@entries_data = array_data.reduce Hash.new, :merge

结果是一个散列,其中一天作为键,计算属性的总和作为值。

然而,这需要每天进行数据库查询:

TimeEntry Load (1.1ms)  SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" IN ('bd9f541c-e37a-45de-bc94-28bef2b5eade')
  TimeEntry Load (0.4ms)  SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" = $1 AND ("time_entries"."created_at" BETWEEN '2016-03-21 04:30:00.000000' AND '2016-03-22 04:29:59.999999')  [["project_id", "bd9f541c-e37a-45de-bc94-28bef2b5eade"]]
  TimeEntry Load (0.2ms)  SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" = $1 AND ("time_entries"."created_at" BETWEEN '2016-03-22 04:30:00.000000' AND '2016-03-23 04:29:59.999999')  [["project_id", "bd9f541c-e37a-45de-bc94-28bef2b5eade"]]
  TimeEntry Load (0.2ms)  SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" = $1 AND ("time_entries"."created_at" BETWEEN '2016-03-23 04:30:00.000000' AND '2016-03-24 04:29:59.999999')  [["project_id", "bd9f541c-e37a-45de-bc94-28bef2b5eade"]]
  TimeEntry Load (0.2ms)  SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" = $1 AND ("time_entries"."created_at" BETWEEN '2016-03-24 04:30:00.000000' AND '2016-03-25 04:29:59.999999')  [["project_id", "bd9f541c-e37a-45de-bc94-28bef2b5eade"]]
  TimeEntry Load (0.5ms)  SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" = $1 AND ("time_entries"."created_at" BETWEEN '2016-03-25 04:30:00.000000' AND '2016-03-26 04:29:59.999999')  [["project_id", "bd9f541c-e37a-45de-bc94-28bef2b5eade"]]
  TimeEntry Load (0.6ms)  SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" = $1 AND ("time_entries"."created_at" BETWEEN '2016-03-26 04:30:00.000000' AND '2016-03-27 04:29:59.999999')  [["project_id", "bd9f541c-e37a-45de-bc94-28bef2b5eade"]]
  TimeEntry Load (0.5ms)  SELECT "time_entries".* FROM "time_entries" WHERE "time_entries"."project_id" = $1 AND ("time_entries"."created_at" BETWEEN '2016-03-27 04:30:00.000000' AND '2016-03-28 04:29:59.999999')  [["project_id", "bd9f541c-e37a-45de-bc94-28bef2b5eade"]]

如何重新设计它以使其只向数据库发送1个查询?

2 个答案:

答案 0 :(得分:1)

不确定这是你的意思,但这是我认为你需要做的事情:

  • 运行查询获取最近N天的所有数据。
  • 按天分组这些记录
  • 在过去N天的每一天中将值合并到{ date => 0}的哈希值

答案 1 :(得分:0)

好的,正如他在回答中提到的tpbowden,我设法将其减少为1个查询:

date_format = "%d %b"
entries_last_week = time_entries.group_by { |t| t.created_at.to_date.strftime(date_format) }.map { |k, v| { k => v.map(&:duration_hours).sum } }
entries_hash = entries_last_week.reduce Hash.new, :merge
today = Date.today
days = (today - 6.days..today).map { |day| { day.strftime(date_format) => 0 } }
hash_of_days = days.reduce Hash.new, :merge

hash_of_days.merge(entries_hash)