views:

735

answers:

3

Let's say I have this model named Product with a field named brand. Suppose the values of brand are stored in the format *this_is_a_brand*. Can I define a method in the model (or anywhere else) that allows me to modify the value of brand before it is called. For example, if I call @product.brand, I want to get This is a Brand, instead of *this_is_a_brand*.

A: 

In your model you can override the method call brand.

def brand
#code to modify the value that is stored in brand
return modified_brand
end

This will allow it to be stored as this_is_a_brand. But, it will be returned as "this is a brand".

Josh Moore
I tried that, but how do I reference the "internal" brand?
sker
Ok, I got it. Attributes are stored in @attributes so I can just call @attributes['brand'] inside the method. Thanks for your help.
sker
+5  A: 

Rather than accessing @attributes directly, you should use read_attribute and write_attribute:

def brand
  b = read_attribute(:brand) 
  b && b.transform_in_some_way
end

def brand=(b)
  b && b.transform_in_some_way
  write_attribute(:brand, b)
end
tomafro
sker
And why is it better to use those methods?
sker
Wait, I get it. Thanks for your help.
sker
webmat
JasonOng
+2  A: 

I would recommend using the square bracket syntax ([] and []=) instead of read_attribute and write_attribute. The square bracket syntax is shorter and designed to wrap the protected read/write_attribute methods.

def brand
  original = self[:brand]
  transform(original)
end

def brand=(b)
  self[:brand] = reverse_transform(b)
end
matthewgarysmith