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!
- Mass Assignment Protection for attributes= is overridable. [↩]
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.