Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create "Upcoming birthdays" module in Rails?

I have a table "users" with a column "date_of_birth" (DATE format with day, month, year). In frontend I need to list 5 upcoming birthdays.

Spent ages trying to work out the logic.. also browsed every possible article in Google with no luck..

Any suggestions how to do this in RoR?

Thanks!

like image 755
Kaspars Upmanis Avatar asked Jun 28 '09 23:06

Kaspars Upmanis


2 Answers

Several answers have suggested calculating/storing day of year and sorting on that, but this alone won't do much good when you're close to the end of the year and need to consider people with birthdays in the beginning of the next year.

I'd go for a solution where you calculate the full date (year, month, day) of each person's next birthday, then sort on that. You can do this in Ruby code, or using a stored procedure in the database. The latter will be faster, but will make your app harder to migrate to a different db platform later.

It would be reasonable to update this list of upcoming birthdays once per day only, which means you can use some form of caching. Thus the speed of the query/code needed is less of an issue, and something like this should work fine as long as you cache the result:

class User
  def next_birthday
    year = Date.today.year
    mmdd = date_of_birth.strftime('%m%d')
    year += 1 if mmdd < Date.today.strftime('%m%d')
    mmdd = '0301' if mmdd == '0229' && !Date.parse("#{year}0101").leap?
    return Date.parse("#{year}#{mmdd}")
  end
end

users = User.find(:all, :select => 'id, date_of_birth').sort_by(&:next_birthday).first(5)

Edit: Fixed to work correctly with leap years.

like image 50
Lars Haugseth Avatar answered Sep 21 '22 22:09

Lars Haugseth


Thanks to this post in my rails 3 app i use:

 u = User.where("strftime('%m%d', date_of_birth) = ?", Date.today.strftime('%m%d'))

Update:

To use this with Postgresql:

u = User.where("extract(month from date_of_birth) = ? AND extract(day from date_of_birth) = ?", Date.today.strftime('%m'), Date.today.strftime('%d'))
like image 34
coding addicted Avatar answered Sep 25 '22 22:09

coding addicted