简体   繁体   English

在轨道中按日期循环遍历对象

[英]Looping through objects by date in rails

I'm trying to loop through records created during a date range by customer then create two arrays to pass to Chart.js. 我试图遍历客户在日期范围内创建的记录,然后创建两个数组以传递给Chart.js。 The first array is each day in the date range, the second is the total hosts scanned for the given day. 第一个数组是日期范围内的每一天,第二个数组是给定日期内扫描的主机总数。

Chart.js is looking for these formats: Chart.js正在寻找以下格式:

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

In my case the labels need to be each date within the given range (I'm just testing it right now with a 14 day range; and data would be the amount of hosts scanned on that given day (which might be 0). 在我的情况下, labels必须是给定范围内的每个日期(我现在只是在14天范围内对其进行测试;而数据将是给定日期内扫描的主机数量(可能为0)。

I can get the total hosts scanned for a Company pretty easily: 我可以很容易地扫描公司的总主机数:

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

But I'm struggling to align the host count with a date range since a test 但自测试以来,我一直在努力使主机数与日期范围保持一致

My code is working, but the count for the day is off by one. 我的代码正在运行,但是一天的计数减少了一个。 In this case, the results from a day like 3/2 are showing under 3/1, etc. 在这种情况下,某天(例如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]

The date range array that I'm feeing into Chart.js looks like: 我对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"]

So the value 17 in the first array should be in position 14, not 13 as it is. 因此,第一个数组中的值17应该在位置14,而不是在位置13。 and so on. 等等。 I can easily adjust this in my code by going back 31 days in, but ideally I want the user to be able to click a 30/60/90 day button and not have the do the backend math to add 1 to the date range. 我可以通过返回31天来轻松地在代码中对此进行调整,但是理想情况下,我希望用户能够单击30/60/90天按钮,而不必执行后端数学运算来将日期范围加1。

I think you should keep it simple. 我认为您应该保持简单。 So it can easily be extended and code readability is higher. 因此可以轻松扩展它,并提高代码可读性。

Here is a snippet which does the same 这是一个功能相同的代码段

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")}

now 现在

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

Read here about group_by 在这里阅读有关group_by的信息

grouped_data[label].try(:length) || 0 grouped_data[label].try(:length) || 0 will return the actual network hosts whose company was created for specific date and 0 for those days where no company was created grouped_data[label].try(:length) || 0将返回在特定日期创建公司的实际网络主机, grouped_data[label].try(:length) || 0则返回没有创建公司的那些日子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM