Group records by both month and year in Rails

Use Group Date.

It supports time zones, so if you ever need to - the code will easily evolve.

https://github.com/ankane/groupdate


Message.select("date_trunc('month', created_at) as month").group("month")

In SQL:

select * from messages group by year(created_at), month(created_at);

In Rails:

Message.all.group_by { |m| m.created_at.beginning_of_month }

To group by year and by month (e.g. not having december 2020 with december 2021):

Message.group("date_trunc('year', created_at), date_trunc('month', created_at)")

Tested on PostgreSQL