Forum: Ruby on Rails HOWTO: Upcoming birthdays partial

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Taylor S. (Guest)
on 2007-03-07 23:31
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! %>

<table>
  <% for upcoming_birthday in @upcoming_birthdays %>
    <tr>
      <td>
          <strong><%= link_to "#{upcoming_birthday.name}", :controller
=> 'people', :action => 'show', :id => upcoming_birthday %></strong><br
/>
          <%= upcoming_birthday.birthdate.strftime("%B %d") %><br />
          <em>will be <%= upcoming_birthday.age + 1 %> years old</em><br
/>
      </td>
    </tr>
  <% end %>
</table>


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.
Pierre-Alexandre M. (Guest)
on 2007-03-08 00:02
(Received via mailing list)
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
 <table>
   <% @upcoming_birthdays.each do |upcoming_birthday| %>
     <tr>
       <td>
           <strong><%= link_to "#{upcoming_birthday.name}", :controller
 => 'people', :action => 'show', :id => upcoming_birthday %></strong><br
 />
           <%= upcoming_birthday.birthdate.strftime("%B %d") %><br />
           <em>will be  pluralize(upcoming_birthday.age + 1,'year')
old</em><br
 />
       </td>
     </tr>
   <% end %>
 </table>


=> 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 |
`========================'
Jonathan V. (Guest)
on 2007-03-08 02:38
(Received via mailing list)
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.
This topic is locked and can not be replied to.