Custom expiry time method

Monday January 16, 2017

Welcome to Rails Church! This is a short post about building a custom method to calculate when a post or invite will expire.

In this example there is a model called invite.rb that has a column called expire_time. We want to be using half hour increments, so I made the data-type float instead of integer. Users can choose how long it will take for the invite to expire in half hour increments when making a new Invite, and this will be saved to the database.

After the invite is saved, wouldn't it be great to show the user an accurate length of time they have before the invite expires? To do this, we will write a custom method to calculate how long it will be from now until expiry.

In the invite model:

def expires_in
  expire_time = self.expire_time
  ((expire_time.hours.since self.created_at) - Time.now)

In the show view we can include this custom calculate with the following:

Expires in: <%= @invite.expires_in %>

This will give us something like Expires in: 12571.555711, which is in seconds. The problem is, it's not very readable by humans. To fix this we can use a helper method to convert this value into human readable values called distance_of_time_in_words. Call the helper method, and pass in the instance variable from above.

Expires in: <%= distance_of_time_in_words(@invite.expires_in) %>

This is an improvement, but it will round the value to the nearest hour, or minute. If you want to be very specific, there is a helpful gem called dotiw (ie. distance of time in words) which will give you very accurate time value interpretations. Include this in your Gemfile and run bundle install.

gem 'dotiw'

Now the output will read something like Expires in: 3 hours, 22 minutes, and 51 seconds.


Written by Robin Hamill

Robin is an independent web application and ecommerce developer living in Toronto. He builds intuitive and functional web apps that engage users and solve problems. He's also excited about climbing rocks, travelling and learning all the things. 💎⛪️