discourse/app/models/concerns/date_groupable.rb
2018-05-03 15:41:41 +02:00

53 lines
1.3 KiB
Ruby

module DateGroupable extend ActiveSupport::Concern
class_methods do
def group_by_day(column)
group_by_unit(:day, column)
end
def group_by_week(column)
group_by_unit(:week, column)
end
def group_by_month(column)
group_by_unit(:month, column)
end
def group_by_quarter(column)
group_by_unit(:quarter, column)
end
def group_by_year(column)
group_by_unit(:year, column)
end
def group_by_unit(aggregation_unit, column)
group("date_trunc('#{aggregation_unit}', #{column})::DATE")
.order("date_trunc('#{aggregation_unit}', #{column})::DATE")
end
def aggregation_unit_for_period(start_date, end_date)
days = (start_date.to_date..end_date.to_date).count
case
when days <= 40
return :day
when days <= 210 # 30 weeks
return :week
when days <= 550 # ~18 months
return :month
when days <= 1461 # ~4 years
return :quarter
else
return :year
end
end
def smart_group_by_date(column, start_date, end_date)
aggregation_unit = aggregation_unit_for_period(start_date, end_date)
where("#{column} BETWEEN ? AND ?", start_date, end_date)
.group_by_unit(aggregation_unit, column)
end
end
end