group_by relative date ranges
I have a client who wants to see a report of her employees grouped by the date they took their last position (date_in_position
). She wants them grouped by: Less than 1 year, 1-3 years, 3-5 years, and over 5 years. I made a little method to return a string usable for the group_by
method, but only "less than 1 year" is working correctly. Everything else shows up as over 5 years.
def dip_range
case self.date_in_position
when 1.year.ago...Date.today
'<开发者_运维技巧; 1 year'
when 3.years.ago...(1.year.ago + 1)
'1-3 years'
when 5.years.ago...(3.years.ago + 1)
'3-5 years'
else
'> 5 years'
end
end
another way to approach it:
def dip_range
case
when self.date_in_position.between?(1.year.ago,Date.today)
'< 1 year'
when self.date_in_position.between?(3.years.ago,(1.year.ago + 1))
'1-3 years'
when self.date_in_position.between?(5.years.ago,(3.years.ago + 1))
'3-5 years'
else
'> 5 years'
end
end
In R1.8 (Time..Date) range doesn't work at all, besides I would rewrite this piece of code anyway:
# self is not required by the way
case (Date.today - date_in_position) / 365.2425
when (0...1)
'< 1 year'
when (1...3)
'< 3 years'
when (3...5)
'< 5 years'
else
'> 5 year'
end
Or even:
years = (Date.today - date_in_position) / 365.2425
case
when years < 1
'< 1 year'
when years < 3
'< 3 years'
when years < 5
'< 5 years'
else
'> 5 year'
end
Integer#years.ago
returns a DateTime
which isn't comparing properly to the Date
objects you are switching on. I'm not exactly sure why this is, but if you change
case self.date_in_position
to case self.date_in_position.to_datetime
this code will work for most cases.
Also, your bounds are incorrect. If someone started work 1 year ago today, they should show as 1-3 years, right? So:
def dip_range
case self.date_in_position
when (1.year.ago+1.day).to_date..Date.today
'< 1 year'
when (3.years.ago+1.day).to_date..1.year.ago.to_date
'1-3 years'
when (5.years.ago.to_date+1.day).to_date..3.years.ago.to_date
'3-5 years'
else
'> 5 years'
end
end
I think this is what you want because it will match in order of priority, change the syntax if you like:
def dip_range
t = self.date_in_position
if t > 1.year.ago
'< 1 year'
elsif t > 3.years.ago
'1-3 years'
elsif t > 5.years.ago
'3-5 years'
else
'> 5 years'
end
end
精彩评论