ruby 42 lines · 7 steps

Building a weekly signups report in Rails

A plain service object that groups records by week and fills in zeros for weeks with no signups.

Explained by highlit
1class WeeklySignupsReport
2 DEFAULT_WEEKS = 12
3 
4 def initialize(weeks: DEFAULT_WEEKS, source: User.all)
5 @weeks = weeks
6 @source = source
7 end
8 
9 def call
10 labels = week_starts
11 counts = counts_by_week
12 
13 labels.map do |week_start|
14 {
15 week: week_start.strftime("%b %-d"),
16 starts_on: week_start.iso8601,
17 signups: counts.fetch(week_start, 0)
18 }
19 end
20 end
21 
22 private
23 
24 attr_reader :source
25 
26 def counts_by_week
27 source
28 .where(created_at: range)
29 .group("DATE_TRUNC('week', created_at)")
30 .count
31 .transform_keys { |timestamp| timestamp.to_date }
32 end
33 
34 def week_starts
35 (0...@weeks)
36 .map { |offset| range.begin.to_date + offset.weeks }
37 end
38 
39 def range
40 @range ||= @weeks.weeks.ago.beginning_of_week..Time.current.end_of_week
41 end
42end
01 / 01
STEP 01

Walkthrough

Space play ←→ step click any line
Three takeaways
  1. 1Injecting the source relation makes the report reusable and easy to test with any scope.
  2. 2Grouping in SQL with DATE_TRUNC pushes aggregation to the database instead of loading every row.
  3. 3Building a complete list of buckets and defaulting missing keys to zero guarantees a gap-free series.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Building a weekly signups report in Rails — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code