在rails中按日期循环对象

时间:2017-03-19 16:16:01

标签: ruby-on-rails arrays ruby

我正在尝试遍历客户在日期范围内创建的记录,然后创建两个数组以传递给Chart.js。第一个数组是日期范围内的每一天,第二个数组是指定日期扫描的总主机数。

Chart.js正在寻找这些格式:

labels: ["3/11","3/12","3/13","3/14"](基本数组) data: [12,13,14,55](另一个基本数组)

在我的情况下,labels需要在给定范围内的每个日期(我现在只测试14天范围;数据将是在给定日期扫描的主机数量(这可能是0)。

我可以非常轻松地获取为公司扫描的总主机数:

count = 0
company.tests.each do |test|
  count += test.network_hosts.count
end

但是我很难将主机数与测试后的日期范围对齐

我的代码正在运行,但当天的计数是一个。在这种情况下,像3/2这样的一天的结果显示在3/1等之下

dates = []
array = []
hit = 0
today = Date.today
tests = company.tests.where(date: today - 30..today).order(date: :asc)
(today - 30..today).each{|date| dates.push(date.to_s)}
dates.each do |r|
  hit = 0
    tests.each do |t|
      if t.date.strftime("%Y-%m-%d") == r
        hit = hit + t.network_hosts.count
      end
    end
    array.push(hit)
  end
  return array
end

=> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

我在Chart.js中收费的日期范围数组如下:

today = Date.today
labels = []
(today - 30..today).each{ |date| labels.push(js_date_time_no_year(date))}
return labels

=> ["02/17", "02/18", "02/19", "02/20", "02/21", "02/22", "02/23", "02/24", "02/25", "02/26", "02/27", "02/28", "03/01", "03/02", "03/03", "03/04", "03/05", "03/06", "03/07", "03/08", "03/09", "03/10", "03/11", "03/12", "03/13", "03/14", "03/15", "03/16", "03/17", "03/18", "03/19"]

因此第一个数组中的值17应该位于第14位,而不是13位。等等。我可以通过回溯31天来轻松地在我的代码中调整此值,但理想情况下,我希望用户能够点击30/60/90天按钮而没有后端数学将1添加到日期范围。

1 个答案:

答案 0 :(得分:0)

我认为你应该保持简单。因此,它可以轻松扩展,代码可读性更高。

这是一个执行相同操作的片段

grouped_data = company.tests.joins(:network_hosts).where(date: 30.days.ago.to_date..Date.today).order(date: :asc).group_by {|test| test.date.strftime("%m/%d")}

现在

array = []
labels = []
(30.days.ago.to_date..Date.today).each do|day|
  label =  day.strftime("%d/%m")
  labels.push label
  array.push(grouped_data[label].try(:length) || 0)
end

关于group_by

,请阅读here

grouped_data[label].try(:length) || 0将返回其公司为特定日期创建的实际网络主机,以及0表示未创建公司的日期