5 Ways to set Attributes in ActiveRecord

Rails 3 allows the developer to change ActiveRecord attributes in various ways. Each one does it slightly differently with sometimes unique side-effects. It’s important you understand which method to use, so here’s a short list (and a neat cheat table at the end!)

user.name = “Rob”

This regular assignment is the most common and easiest to use. It is the default write accessor generated by Rails. The name attribute will be marked as dirty and the change will not be sent to the database yet.

You can undo the change by calling reload! or save the change to the database by calling save.

user.write_attribute(:name, “Rob”)

This is the method that is called by the default accessor above. A synonym for this function is user[:name] = “Rob”. It also has a read_attribute counterpart.

Just like above, this method does not yet change the attribute in the database. Use this method anywhere you need to bypass the default write accessor above, for example when you want to write a custom attribute= writer.

user.update_attribute(:name, “Rob”)

This method will change the attribute in the model and pass it straight to the database, without running any validations.

Two gotchas:

  • Any other changed attributes are also saved to the database.
  • Validations are skipped so you could end up with invalid data.

Because of that last quirk it’s a good practice to use update_attributes instead.

user.attributes = {:name => “Rob”}

This method will set all the attributes you pass it, except those who are protected from mass assignment if you’re using attr_protected or attr_accessible. The changes are not saved to the database.

You can override the mass assignment protection by passing false:

user.send(:attributes=, {:name => "Rob"}, false)

user.update_attributes(:name => “Rob”)

This method changes the attributes of the model, checks the validations, and updates the record in the database if it validates. Since it uses the above attributes= method, attributes protected from mass assignment are not changed.

Note that just like update_attribute this method also saves other changed attributes to the database.

Handy Cheat Sheet Table

Method Uses Default Accessor Mass Assignment Protection Saved to Database Validations
attribute= Yes No No n/a
write_attribute No No No n/a
update_attribute Yes No Yes No
attributes= Yes Yes1 No n/a
update_attributes Yes Yes Yes Yes

If you want to understand more about these methods I suggest you check out their source code. Each time it’s only a couple of lines and it will really broaden your understanding of how Rails works!

  1. Mass Assignment Protection for attributes= is overridable. []
This entry was posted in Ruby on Rails. Bookmark the permalink.

One Response to 5 Ways to set Attributes in ActiveRecord

  1. Excellent post. I want to thank you for this informative read, I really appreciate
    sharing this great post. Keep up your work. Thanks for this very useful info you
    have provided us.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">