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!
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.
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'))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With