1. Skip to navigation
  2. Skip to content

The ELC Community Blog

A knowledge exchange on Ruby on Rails and Agile Development


ActiveRecord attribute update semantics

by Ryan Garver on February 20, 2007

ActiveRecord (AR) provides a number of great features. One feature that is often taken for granted is the mapping of table columns (attributes) to class signals. We use this feature of AR without thinking about it.

  
   1  article = Article.find(1)
   2  article.attributes[:title] #=> "A Blog Posting"
   3  article.title #=> "A Blog Posting"

We also can take this several steps further and modify how AR responds to requests for the value of a attribute. Jamis Buck had a recent blog post outlining an interesting way to set up default values for an attribute than can depend on another attribute. The difficulty in AR comes when you need to modify what happens when attributes are being updated. A great example of this is if you want an action to always happen when (say) you assign an

   1  Author
to
   1  Article.author
. AR has several different ways of getting and setting attributes out of the database. We'll focus on the setting since that is often the confusing part of AR hacking. You should pay attention to the underlying implementation mentioned below; it's easy to accidentally create infinite recursion.

   1  article.attributes[:attr_name]=value
Every AR object has an
   1  attributes
Hash that contains the
   1  name=>value
pairs that correspond to the columns and their values for the object. This Hash is bi-directional and therefore can be modified. Once the
   1  attributes
Hash has been updated you can save the AR object and those updates will persist. Much of the alternative methods of updating AR objects are built on this base. The
   1  attr_name
can be either a string or a symbol.
   1  article.attr_name=value
This assigns
   1  attr_name
with
   1  value
within the in-memory AR object. To commit the change you must call
   1  save
on the AR object. This ends up calling
   1  []=
under the hood. When overwriting how the attributes are updated in a AR object you'll want to override this method and do the final assignment using
   1  []=
.
   1  article.update_attribute(:attr_name, value)
This assigns the
   1  value
to
   1  attr_name
and saves the value to the database all in one go. Behind the scene this calls the
   1  article.attr_name=
to do the assignment which means that you can override how this assignment takes place. This method of assignment also skips validation on the attribute.
   1  article.update_attributes(:attr_name1 => value1, :attr_name2 => value2, ...)
This method is the same as calling
   1  []=
for each
   1  name=>value
pair and then saving.

A quick note. When overloading the assignment of association do not try to do the overloading on (for example) the

   1  author=
method, but rather the
   1  author_id=
method. Otherwise you confuse AR and it doesn't call your methods.

Comments

Add a comment


home | services | Ruby on Rails Development | code | blog | company