Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

decorating an attribute in rails

I have a name attribute on a Person model and every time I access the name attribute, I want name.capitalize to be returned.

Doing the following inside the model won't work,

def name
  name.capitalize
end

so what is the alternative?

like image 889
user16455 Avatar asked Jul 17 '09 15:07

user16455


2 Answers

I suggest you to create a secondary method with your custom formatters.

class Person

  def formatted_name
    name.capitalize
  end

end

This is a better solution compared with overwriting the default implementation because setter and getters might called when updating/writing/saving the record to the database. I remember once when I overwrote the default implementation of an attribute and each time a record was saved, the attribute was updated with the formatted value.

If you want to follow this way you can use alias_method_chain or take advantage of inheritance including an external module.

class Person

  def name_with_formatter
    name_without_formatter.capitalize
  end
  alias_method_chain :name, :formatter

end

Also you can overwrite name and call read_attribute(:name) from within your custom method.

def name
  read_attribute(:name).capitalize
end

def name
  self[:name].capitalize
end

Again, don't do this. Go ahead and create a custom method.

like image 98
Simone Carletti Avatar answered Oct 22 '22 10:10

Simone Carletti


But happens when name is null?

capitalize will throw an undefined method for nil::Class if self[:name] returns nil.

The following covers that:

def name
  self[:name] ? self[:name].capitalize : nil
end

But I agree that you should create the formatted method and leave the name method as is. Never know when you might need the raw data.

FYI: the reason why your method didn't work was because it was causing, what I like to call, a self referring loop. You are redefining the method but calling the method in the new method. So you have to use self[:name] or read_attribute to get to the internal model data.

like image 41
Tony Fontenot Avatar answered Oct 22 '22 12:10

Tony Fontenot