Overloading the ActiveRecord Setter

Sometimes, you want to do some extra work when you set an attribute on your ActiveRecord model instance.

You can’t just do this, because you’ll just end up recursively calling the very setter that you’re defining:

class Square < ActiveRecord::Base
    def side=(value)
        self.area = value*value
        self.side = value
    end
end
&#91;/sourcecode&#93;
<div>...and you can't do this because you'll end up modifying a copy of the attributes hash of the model instance, which will not be written through to the database when the model instance is saved ( check out ActiveRecord::Base::attributes in active_record/base.rb):</div>

class Square &gt; ActiveRecord::Base
    def side=(value)
        self.attributes['side'] = value
        self.area = value * value
    end 
end
After looking through the source for ActiveRecord::Base and some testing, I’ve found a method that’s worked for me and appears to be the preferred way of doing it:
class Square &gt; ActiveRecord::Base
    def side=(value)
        self.area = value * value # This would still work because we're calling the default setter for area
        write_attribute('side', value)
    end
end
Alternatively, you could do “self[‘side’] = value” instead of write_attribute.   The index assignment operatore actually does the same thing.
Advertisements

January 13, 2009. Tags: . Uncategorized.

Leave a Comment

Be the first to comment!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Trackback URI

%d bloggers like this: