Search code examples
ruby-on-railsrubyruby-on-rails-3ruby-on-rails-3.1ruby-on-rails-3.2

Rails how to create chart data for each month between 2 dates?


In my model I have:

  def self.chart_data(start, slut)
  if start.nil?
  start = 2.weeks.ago
  end

  if slut.nil?
  slut = Date.today
  end

    range = start.to_date..(slut.to_date + 1.day)

  if start.to_date.beginning_of_month.to_s != slut.to_date.beginning_of_month.to_s

kliks = count(
  :group => 'date(month)',
  :conditions => { :created_at => range }
)
  # CREATE JSON DATA FOR EACH MONTH - PROBLEM HERE
  (range).map(&:beginning_of_month).uniq.map(&:to_s).each do |month|
    {
      created_at: month,
      clicks: kliks[month] || 0
    }
  end


  else

  kliks = count(
  :group => 'date(created_at)',
  :conditions => { :created_at => range }
)

  #WORKS FINE DATA FOR EACH DAY
  (start.to_date..slut.to_date).map do |date|
    {
      created_at: date.strftime("%F"),
      clicks: kliks[date] || 0
    }
  end
 end
end

I have added a column month to my table. That is the beginning_of_month of the created_at column. So that is easy to group by month. But how do I create the JSON data for each month? Currently it dosen't work. But the data for each day works fine.

The result for Klik.chart_data("1/8/2012", "22/9/2012")

    <div data-clicks="[{&quot;created_at&quot;:&quot;2012-09-08&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-09&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-10&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-11&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-12&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-13&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-14&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-15&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-16&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-17&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-18&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-19&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-20&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-21&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-22&quot;,&quot;clicks&quot;:11}]" id="click_chart">

First answer result:

<div data-clicks="[{&quot;created_at&quot;:&quot;2012-09-08&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-09&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-10&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-11&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-12&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-13&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-14&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-15&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-16&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-17&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-18&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-19&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-20&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-21&quot;,&quot;clicks&quot;:0},{&quot;created_at&quot;:&quot;2012-09-22&quot;,&quot;clicks&quot;:11}]" id="click_chart">

Solution

  • Try to use

    (start.to_date..slut.to_date).map(&:beginning_of_month).uniq.map do |date|
      {
        created_at: date.strftime("%F"),
        clicks: kliks[date] || 0
      }
    end
    

    or

    (start.to_date.beginning_of_month..slut.to_date).reject{|date| date.day !=1}.map do |date|
      {
        created_at: date.strftime("%F"),
        clicks: kliks[date] || 0
      }
    end