# HOWTO: Upcoming birthdays partial

**URL:** <https://www.ruby-forum.com/t/howto-upcoming-birthdays-partial/88075>\
**Category:** Rails\
**Created:** [March 7, 2007, 10:31pm UTC](https://www.ruby-forum.com/t/howto-upcoming-birthdays-partial/88075 "2007-03-07T22:31:26Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![taylorstrait](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b5a626/32.png) [@taylorstrait](https://www.ruby-forum.com/u/taylorstrait)\
**Post date:** [March 7, 2007, 10:31pm UTC](https://www.ruby-forum.com/t/howto-upcoming-birthdays-partial/88075/1 "2007-03-07T22:31:26Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![taylorstrait](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b5a626/32.png) [@taylorstrait](https://www.ruby-forum.com/u/taylorstrait)\
**Post date:** [March 7, 2007, 11:02pm UTC](https://www.ruby-forum.com/t/howto-upcoming-birthdays-partial/88075/2 "2007-03-07T23:02:15Z")

</div>

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 |  
`========================’

---

<div class="post-metadata">

**Author:** ![taylorstrait](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/b5a626/32.png) [@taylorstrait](https://www.ruby-forum.com/u/taylorstrait)\
**Post date:** [March 8, 2007, 1:38am UTC](https://www.ruby-forum.com/t/howto-upcoming-birthdays-partial/88075/3 "2007-03-08T01:38:38Z")

</div>

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.
