Last Updated: February 25, 2016
·
794
· countxyz

Rails Date Search Using Ruby's Range Class

I recently had to implement a date search feature in Rails using redis.

problem:

Fetching the values involved iterating through each date within the date period and adding up the values like so:


$redis.hmget "stats/client:#{id}", *keys(beg_p, end_p)

The book I was referencing implemented *keys like so:


def keys(beg_p, end_p)
  keys = []
  while beg_p <= end_p
    keys << if block_given?
      yield(beg_p.to_s(:number))
    else
      beg_p.to_s(:number)
    end
    beg_p += 1.day
  end

  keys
end

Enter stage right: Ruby's Range Class to provide a simpler, more expressive, and elegant solution.


(1..5).to_a
=> [1, 2, 3, 4, 5]

('a'..'e').to_a
=> ["a", "b", "c", "d", "e"]

start_date = Date.new(2014, 8, 30)
=> Sat, 30 Aug 2014

end_date = Date.new(2014, 9, 2)
=> Tue, 02 Sep 2014

((start_date)..(end_date)).to_a
=> [
  [0] Sat, 30 Aug 2014,
  [1] Sun, 31 Aug 2014,
  [2] Mon, 01 Sep 2014,
  [3] Tue, 02 Sep 2014
]

My final implementation for *keys:


def get_every_date(starting, ending)
  starting = Date.parse(starting).to_s(:number)
  ending   = Date.parse(ending).to_s(:number)
  ((starting)...(ending)).to_a
end

Voila!