HiveBrain v1.2.0
Get Started
← Back to all entries
patternrubyrailsMinor

Ruby method that returns an age from a date of birth

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
agemethoddatebirththatreturnsrubyfrom

Problem

I have a method on my user model to calculate the user's age and return a human readable string. My user's can be between 1 month old and above so the returned string is different depending on if the person is "2 months old" or "1 year old" or "2 years and 3 months old".

I have reviewed a few SO posts to come to this solution. Is there anything I am missing? Leap years?

def age
    dob = self.date_of_birth

    # if a date of birth is not nil
    if dob != nil 

      # get current date  
      now = Date.current

      # has person had their birthday yet this year
      had_birthday = ((now.month > dob.month || (now.month == dob.month && now.day >= dob.day)) ? true : false) 

      # if yes then subtract this year from birthday year, if not then also subtract 1 to get how many full years old they are
      years = now.year - dob.year - (had_birthday ? 0 : 1)

      # get the calendar month difference from birthdya calendar month and today's calendar month.  if they have not had their birthdya yet then subtract the difference from 12
      months = had_birthday ? now.month - dob.month : 12 - (now.month - dob.month)

      # for under 1 year olds
      if years == 0
        return months > 1 ? months.to_s + " months old" : months.to_s + " month old"  

      # for 1 year olds
      elsif years == 1
        return months > 1 ? years.to_s + " year and " + months.to_s + " months old" : years.to_s + " year and " + months.to_s + " month old" 

      # for older than 1
      else
        return months > 1 ? years.to_s + " years and " + months.to_s + " months old" : years.to_s + " years and " + months.to_s + " month old"
      end

    # No date of birth saved so can not calculate age
    else
      return "No Date of Birth"
    end
  end

Solution

Make an additional function to handle plural

In-lining the extra logic to handle the plural is messy, I suggest a small separate method:

def plural(word, value)
  "#{value.to_s} #{word}#{value > 1 ? 's' : ''}"
end


Reduce nesting by returning early

If you write

if dob == nil
  return "No Date of Birth"
end


You can reduce nesting in the rest of the function and highlight the handling of the special case.

Code Snippets

def plural(word, value)
  "#{value.to_s} #{word}#{value > 1 ? 's' : ''}"
end
if dob == nil
  return "No Date of Birth"
end

Context

StackExchange Code Review Q#121929, answer score: 3

Revisions (0)

No revisions yet.