Kilka odpowiedzi sugerowało obliczanie/przechowywanie dnia roku i sortowanie, ale samo to nie przyniesie wiele dobrego, gdy zbliżasz się do końca roku i musisz wziąć pod uwagę osoby, które mają urodziny na początku przyszłego roku.
Wybrałbym rozwiązanie, w którym obliczasz pełną datę (rok, miesiąc, dzień) następnych urodzin każdej osoby , a następnie posortuj według tego. Możesz to zrobić w kodzie Rubiego lub za pomocą procedury składowanej w bazie danych. Ta ostatnia będzie szybsza, ale utrudni późniejszą migrację Twojej aplikacji na inną platformę bazy danych.
Rozsądnie byłoby aktualizować tę listę nadchodzących urodzin tylko raz dziennie, co oznacza, że możesz użyć jakiejś formy buforowania. W ten sposób szybkość wymaganego zapytania/kodu nie stanowi większego problemu, a coś takiego powinno działać dobrze, o ile buforujesz wynik:
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)
Edytuj :Poprawiono działanie z latami przestępnymi.