☰
×
Jonathan ThomBlogProjectsContact

Querying for Today's Date with ActiveRecord

3.10.2017


Seems like it should be simple, right? Well it is, locally. But when pushed to production, I ran into some odd bugs having to do with this seemingly simple task.

I built an application for personal trainers to post workouts for their clients. (It's here, but still very much a work in progress). One of the features is that when an athlete (or a coach of that athlete) goes to their home page, their training session for that day is featured. It works like this: When a workout is created, it has an attribute, date, that takes a ruby Date object. Then, when querying the database, I just ask for all the workouts where the date is Date.today (and the athlete is the current one). The method looked like this:

scope :today, ->(athlete) { where(date: Date.today).where(athlete_id: athlete.id) }

This worked great until I pushed to production (and maybe that wasn't even the issue, but that's where I noticed it). I found that the featured workout was not today's, but tomorrow's (or nothing, if there wasn't a workout for tomorrow). And when I asked the Rails console what Date.today was, sure enough, it said tomorrow.

Why? Well, I'm pretty sure it's because the time zone defaulted to UTC, aka Greenwich Mean Time. So by 4pm, it was "tomorrow." So the first step was to actually tell my app what time zone I want to default to. In config/application.rb, inside of the Application class, that looks like this:

config.time_zone = 'Pacific Time (US & Canada)' config.active_record.default_timezone = :local

But this didn't quite work. The query was still turning up the wrong date in production, or nothing at all. So I turned to my good friend Stack Overflow, who introduced me to this thread.

As I understand it, Date.today is not specific enough, as the Date object being created in ActiveRecord has a time stamp connected to it. Comparing my old query vs the one suggested in the SO thread in the Rails console showed this:

Date.today # => Fri, 10 Mar 2017

Time.zone.now.beginning_of_day # => Fri, 10 Mar 2017 00:00:00 PST -08:00

Plugging that into my query looks like this:

scope :today, ->(athlete) { where(date: Time.zone.now.beginning_of_day).where(athlete_id: athlete.id) }

I pushed back to production and...nothing. It didn't work for workouts previously posted. BUT, when I posted a new one for "today" - it worked! I will check again later (once it's past midnight in England) to double check, but I'm pretty sure this takes care of it. I'll update this post to reflect my results.

Perhaps there's a simpler solution that this, or I'm not understanding it all perfectly, but it's working, so I'll take it!

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

Grouping Records by Month with Ruby

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

Getting the Action Mailer to Actually Mail (with Mailgun)

Advice for New Epicodus Students