Suppose you want the ability to find all current birthdays or all upcoming birthdays – how would you go about doing it?
The first approach – finding records that have today’s date as their birthday is fairly straight forward. (We’re assuming that the ‘records’ we’re dealing with here are employee records, people records, etc… Something that would obviously have a date of birth field) We just need to keep in mind that when we create the query, we must omit the year. We’d accomplish this by writing the below:
def self.todays_birthdays
#return array of employee objects whos birthday it is today based on MM/DD
Employee.where("strftime('%m%d', date_of_birth) = ?", Date.today.strftime('%m%d'))
end
But what about when you want to show upcoming birthdays? I’m not going to lie, it did take me a little bit to figure this one out. Luckily for us, Ruby has a few nice built in methods to help us out: #days.ago and #days.from_now to the rescue:
def self.upcoming_birthdays
#return array of employee objects who have an upcoming birthday within the next 14 days
Employee.where(date_of_birth: 0.days.ago .. 14.days.from_now)
end
Combine those two methods, along with the ability to create ranges ( .. and … ) we’re able to return an array of upcoming objects who have a birthday that falls within THE RANGE of dates we specify, which in this case is between today (o.days.ago) and 14 days from now (14.days.from_now).
One fallacy that developers might tend to run in to is to simply return all objects who have a birthday in a given month. The issue with that, however, is what if we’re on the last day of the month and someone has a birthday on the first day of the next month? We’d have no viability into their birthday until after midnight when the numerical value of the month changes. Creating a query that returns a list based on a range of days is probably the most effective methodology as it will account for that use case, as well as on the dreaded leap year as well.