Skip to content

Instantly share code, notes, and snippets.

@adamkleingit
Last active December 20, 2015 08:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save adamkleingit/6097795 to your computer and use it in GitHub Desktop.
Save adamkleingit/6097795 to your computer and use it in GitHub Desktop.
500Tech / Rails Riddles #2
# Improve / Fix as many things in the code below
# Answers should be sent to hackademy@500tech.com
# Good luck
class User < ActiveRecord::Base
validates_presence_of :name, :email, :date_of_birth, :age_category
before_save do
age = (Time.now - date_of_birth).year
if age < 10 age_category = 'child'
elsif age < 18 age_category = 'teenager'
elsif age < 24 age_category = 'young'
elsif age < 54 age_category = 'adult'
else age_category = 'senior'
end
end
@adamkleingit
Copy link
Author

Send answers privately to hackademy@500tech.com. No spoilers!

Copy link

ghost commented Sep 6, 2013

Improvement number 1 - name your callback!

before_save :set_age_category

protected
def set_age_category
...

Copy link

ghost commented Sep 6, 2013

Improvement number 2 - use small methods for reusablility and readability

def age
  (Time.now - date_of_birth).year
end

def set_age_category
  if age < 10....
end

Copy link

ghost commented Sep 8, 2013

Fix number 1 - trying to set an active record attribute from within a method requires an explicit use of 'self':

def set_age_category
  ...
  self.age_category = ...
end

Copy link

ghost commented Sep 8, 2013

Improvement number 3 - use array and loop over a hash to set the age category (many other possible solutions for this):

CATEGORIES = [[10, 'child'],
                               [18, 'teenager'],
                               [24, 'young'],
                               [54, 'adult'],
                               [200, 'senior']]
...
def set_age_category
  self.age_category = CATEGORIES.take_while { |category| category[0] < age}.last[1]
end

Copy link

ghost commented Sep 8, 2013

Improvement number 4 - define age_category as a method so that whenever we use it it's correct (and not just after we save):

def age_category
   CATEGORIES.take_while { |category| category[0] < age}.last[1]
end

def set_age_category
  self[:age_category] = age_category
end

Copy link

ghost commented Sep 8, 2013

Fix number 2 - don't validate age_category (because it is a calculated field)

validates_presence_of :name, :email, :date_of_birth
```ruby

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment