HOWTO: Upcoming birthdays partial


#1

I searched for this info earlier and only found other people asking how
to do this. So, now that I have done it I though I would add it to the
archives:

_UPCOMING_BIRTHDAYS.RHTML

<% @upcoming_birthdays = Person.find(:all, :conditions => “birthdate is
NOT NULL”) %>
<% @upcoming_birthdays.delete_if {|person|
Time.today.strftime("%j").to_i > person.birthdate.strftime("%j").to_i }
%>
<% @upcoming_birthdays.delete_if {|person|
person.birthdate.strftime("%j").to_i > (Time.today.strftime("%j").to_i)

  • 31 } %>
    <% @upcoming_birthdays.sort! %>
<% for upcoming_birthday in @upcoming_birthdays %> <% end %>
<%= link_to "#{upcoming_birthday.name}", :controller => 'people', :action => 'show', :id => upcoming_birthday %> <%= upcoming_birthday.birthdate.strftime("%B %d") %>
will be <%= upcoming_birthday.age + 1 %> years old

PERSON.RB

def <=>(other)
birthdate.strftime("%j").to_i <=>
other.birthdate.strftime("%j").to_i
end

def age
((Date.today - birthdate)/365.2422).to_i
end

COMMENTS
This assumes that birthdates are stored as date and not datetime. The
only tricky part is that you have to teach Class Person how to .sort!
with <=>. Everything else should be self-explanatory. Learn to love
strftime.


#2

Maybe you shouldn’t put business model in your view:

=> Person.rb
def self.find_upcoming_birthdays
find_all(:conditions => “birthdate is NOT NULL”)
end

def <=>(other)
birthdate.strftime("%j").to_i <=>
other.birthdate.strftime("%j").to_i
end

def age
((Date.today - birthdate)/365.2422).to_i
end

=> _upcoming_birthdays.rhtml

<% @upcoming_birthdays.each do |upcoming_birthday| %> <% end %>
<%= link_to "#{upcoming_birthday.name}", :controller => 'people', :action => 'show', :id => upcoming_birthday %>
<%= upcoming_birthday.birthdate.strftime("%B %d") %>
will be pluralize(upcoming_birthday.age + 1,'year') old

=> Controller
@upcoming_birthdays = Person.find_upcoming_birthdays
@upcoming_birthdays.delete_if {|person|
Time.today.strftime("%j").to_i >
person.birthdate.strftime("%j").to_i
}
@upcoming_birthdays.delete_if {|person|
person.birthdate.strftime("%j").to_i >
(Time.today.strftime("%j").to_i) + 31 }

@upcoming_birthdays.sort!

Just my $0.02.


,========================.
| Pierre-Alexandre M. |
| email : removed_email_address@domain.invalid |
`========================’


#3

Here’s how I find upcoming/recent birthdays in a Person model:

Find people with birthdays around a given date.

:date - Date to anchor around. Defaults to today.

:back - Number of days to go back. Defaults to 7.

:forward - Number of days to look forward. Defaults to 14.

def self.find_by_birthday(options = {})
options = options.reverse_merge(:date => Date.today, :back => 7,
:forward => 14)

birthday = sanitize_sql(["dayofyear(date_of_birth) - dayofyear(?)",

options[:date]])

find(:all, :select => "people.*, #{birthday} AS birthday",
     :conditions => ["date_of_birth is not null and #{birthday} >= 

-?
and #{birthday} <= ?", options[:back], options[:forward]],
:order => “birthday”)
end

-Jonathan.