I would like to start a conversation about the subtle difference between update_attribute and update_attributes, namely that update_attribute skips validations and update_attributes does not skip validations.
I know this has been around for a while but is Rails 4 the time to make them both respect validations? I am willing to do the work if the core team feels like it would be a worthwhile breaking change.
I don’t have a ton of context on the history but as I talk to more and more beginners (and advanced) Rails folks, that subtle difference does trip people up.
The purpose of update_attribute was to be able to touch an attribute fast, set a flag for example… something you know can go straight to the database. Indeed, update_attribute has never run validations.
There was some discussion about this method for Rails 3 because if the goal was to bypass stuff to be fast it didn’t felt consistent to still go through the callbacks. And for some time update_attribute skipped also callbacks in edge:
Perhaps off topic – I’ve got an unreleased gem that patches save() and create() in ActiveRecord so that you can skip callbacks (and validations, although I know you can already do that). You’d do something like obj.save(:skip_callbacks => true, :skip_validations => true).
Is there a reason this behaviour is absent from ActiveRecord? Would people welcome it if I submitted a pull request with this feature?
I don't think that the 's' is a big enough change to make it
noticeable. I like update_column, maybe a bang method would make sense
too. But I'd expect them to both run validations.
Knowing that history, I like Steve’s idea of deprecating update_attribute and advertising update_column as the fast way to update a single column and update_attributes as the way to run through the whole update “stack”.
I personally find confusing the difference between update_attributes and update_attribute. Intuitively, it seems that it is only a matter of plural/singular (the first one changes more than one attribute through a Hash argument and the second one changes only one through a column and a value argument). Therefore, the implicitly validation skipping is something that I (and when I say I, I’m saying IMHO) dislike.
Cool, so after this thread and some discussion we have decided to deprecate update_attribute in 3-2-stable and remove it in Rails 4. Nowadays it has little sense, and the singular/plural distinction does not seem to deserve a dedicated method that does the same (if we added validations to update_attribute).
Would anyone be so kind as to volunteer a pull request for this?
I think that would be a different discussion with a different patch. Let this one be focused on the deprecation + removal.
I think the use case “only skip validations” is rare, and historically people used update_attribute as the closest we have to update_column. I believe the deprecation message should point to update_column, with minor emphasis buy mentioning also update_attributes.
I know this change made it into 4.0, with a deprecation in 3.2 and was later reverted (I believe) so as not to deprecate functionality in a patch release.
I think the intent was for update_attribute to still be deprecated in 4.0. Is this right?
If so, I’ve submitted a pull request to do this deprecation: