☰
×
Jonathan ThomBlogProjectsContact

Grouping Records by Month with Ruby

2.21.2018


I recently found a nice use for ruby's group_by method. I am building a blog for a friend and I to use, and wanted to display all of the old posts in the sidebar, grouped by month. Sort of like this:

January 2018

Why I Broken My New Year's Resolution After Two Weeks My New Year's Resolution

December 2017

The Santa Clause, a Philosophical Debate

November 2017

Why Stuffing is the Best Thanksgiving Food If You Don't Like Pumpkin Pie, You Hate Freedom

Provided my records have timestamps, this can be done like this:

def grouped_by
  all.group_by { |post| post.created_at.beginning_of_month }
end

I also used a method, .ordered, that sorted them newest to oldest: order(created_at: :desc).

Post.ordered.grouped_by_month returns a hash that looks something like this:

{
  Mon, 01 Jan 2018 00:00:00 UTC +00:00=>[#<Post attributes...>, #<Post attributes...>],
  Fri, 01 Dec 2017 00:00:00 UTC +00:00=>[#<Post attributes...>],
  Wed, 01 Nov 2017 00:00:00 UTC +00:00=>[#<Post attributes...>, #<Post attributes...>]
}

All posts are not grouped by the first day of the month they were created in. To loop through this and use it in a view, you need to use two iteration variables, one for dates, and one for posts. And then loop through the posts once you have those isolated. My approach looked like this (where @posts = Post.ordered):

- @posts.grouped_by_month.each do |date, posts|
  h3 = date.strftime("%B %Y")
  - posts.each do |post|
    p
      = link_to post_path(post) do
        = post.title

(The markup is slim templating, by the way. Once you make the switch to it, you will never go back).

Enumberables are a super powerful and fun way to do interesting things with your ruby collections. I often have to remind myself that using ActiveRecord (especially joins in lieu of say, .select) is often the better choice. But I think cases like the one above are a perfect chance to flex ruby's muscles.

Other Posts

The Best Projects Can Be Done in a Weekend

Everyone Has Something To Offer

Book Thoughts: Capital and Ideology

Naive Diffie-Hellman Implementation in Ruby

PGP/GPG

Lessons from Sandi Metz

When Does the Magic Comment Work, and When Does it Not?

Benchmarking Arrays Full of Nils

Go, and When It's Okay to Learn New Things

Favorite Talks from RailsConf

Front End Refactor

Add Timestamps to Existing Tables in Rails

Let Your Projects Breathe

The Busy and (Somewhat) Fit Developer

TuxedoCSS and the Rails Asset Pipeline

Gem You Should Know About: auto_html

Querying for Today's Date with ActiveRecord

Getting the Action Mailer to Actually Mail (with Mailgun)

Advice for New Epicodus Students