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*.
-
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 endThis will allow it to be stored as this_is_a_brand. But, it will be returned as "this is a brand".
sker : 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. -
Rather than accessing @attributes directly, you should use
read_attributeandwrite_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) endsker : What does the idiom b && b.transform_in_some_way mean?sker : And why is it better to use those methods?sker : Wait, I get it. Thanks for your help.webmat : For the other ppl not getting it: b && b.... is a common Ruby idiom. what's after the && is only executed if b is not nil. See also the andand gem for the same functionality: b.andand.transform_in_some_wayJasonOng : Ah... nice. Great tip on using && -
I would recommend using the square bracket syntax (
[]and[]=) instead ofread_attributeandwrite_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
0 comments:
Post a Comment