ActiveRecord update_attribute vs update_attributes

3,006 views
Skip to first unread message

MikeGehard

unread,
Jun 13, 2012, 11:37:52 AM6/13/12
to rubyonra...@googlegroups.com
Greetings all,

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. 

Thanks,
Mike

Andrés Mejía

unread,
Jun 13, 2012, 11:13:26 PM6/13/12
to rubyonra...@googlegroups.com
+1 for making update_attribute run validations.

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-core/-/tdnUJ-TqutEJ.
To post to this group, send email to rubyonra...@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-co...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.

Xavier Noria

unread,
Jun 14, 2012, 5:17:38 AM6/14/12
to rubyonra...@googlegroups.com
There is some bit of history here.

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:


though it still touched updated_at, so fast but not quite there.

That method is so popular, however, that the change felt too risky because it was subtle, and that was reverted just before shipping:


In the end, in 3.1 it was decided to introduce instead a new method update_column. That is the fast one.

Given the current status of things, I personally agree that running validations in update_attribute in Rails 4 would be a good idea.

Let's see what other core team members think though. Thoughts?


Steve Klabnik

unread,
Jun 14, 2012, 7:39:38 AM6/14/12
to rubyonra...@googlegroups.com
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.

Maybe deprecating one is a good idea.

MikeGehard

unread,
Jun 14, 2012, 8:31:22 AM6/14/12
to rubyonra...@googlegroups.com
Thanks for the history lesson Xavier.

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".

Simon de Boer

unread,
Jun 14, 2012, 9:15:30 AM6/14/12
to rubyonra...@googlegroups.com
FWIW: This subtle difference disturbed me so much that I just alias update_attribute to update_attributes.  

I'm very pleased to learn about update_column for the strange edge case where you need it direct.

+1 for deprecation and emphasizing update_column.

Peter Inglesby

unread,
Jun 14, 2012, 5:49:03 AM6/14/12
to rubyonra...@googlegroups.com
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?

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.

Rodrigo Flores

unread,
Jun 14, 2012, 10:02:36 AM6/14/12
to rubyonra...@googlegroups.com
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.

I'm +1 for the change :).

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-core/-/tvA_NDIEJ5QJ.

Xavier Noria

unread,
Jun 14, 2012, 12:18:53 PM6/14/12
to rubyonra...@googlegroups.com
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?

Steve Klabnik

unread,
Jun 14, 2012, 12:34:39 PM6/14/12
to rubyonra...@googlegroups.com
I'll give it a go right now.

Brian Morearty

unread,
Jun 14, 2012, 12:36:58 PM6/14/12
to rubyonra...@googlegroups.com
Steve,

It'd be cool if the patch included the addition of a :validate => false option in update_attributes.

This would make for an easier upgrade path from update_attribute.

Brian

Xavier Noria

unread,
Jun 14, 2012, 12:40:14 PM6/14/12
to rubyonra...@googlegroups.com
On Thu, Jun 14, 2012 at 6:36 PM, Brian Morearty <bmor...@gmail.com> wrote:
Steve,

It'd be cool if the patch included the addition of a :validate => false option in update_attributes.

This would make for an easier upgrade path from update_attribute.

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.

Rodrigo Flores

unread,
Jun 14, 2012, 12:43:48 PM6/14/12
to rubyonra...@googlegroups.com
Xavier

I think I can give you a hand adding the deprecation. 



--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.

Xavier Noria

unread,
Jun 14, 2012, 12:49:12 PM6/14/12
to rubyonra...@googlegroups.com
On Thu, Jun 14, 2012 at 6:43 PM, Rodrigo Flores <ma...@rodrigoflores.org> wrote:
Xavier

I think I can give you a hand adding the deprecation. 

Thanks Rodrigo, Steve already volunteered though :).

Matt Jones

unread,
Jun 14, 2012, 1:20:56 PM6/14/12
to rubyonra...@googlegroups.com

On Jun 14, 2012, at 12:36 PM, Brian Morearty wrote:

> Steve,
>
> It'd be cool if the patch included the addition of a :validate => false option in update_attributes.
>
> This would make for an easier upgrade path from update_attribute.

Note that there's one additional difference, due to attribute whitelisting. Thus:

some_object.update_attribute(:foo, 'bar')

is NOT the same as:

some_object.update_attributes(foo: 'bar')

if foo isn't mass-assignable.

Not sure if it's terribly relevant, but worth mentioning.

--Matt Jones

Steve Klabnik

unread,
Jun 14, 2012, 6:03:10 PM6/14/12
to rubyonra...@googlegroups.com
This has now been merged, in both master and 3.2. Good job everyone!

Andrew Mutz

unread,
Feb 22, 2013, 12:32:03 PM2/22/13
to rubyonra...@googlegroups.com
Hello,

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:


Is it indeed intended to be deprecated?

Thanks,
Andrew.


On Thu, Aug 9, 2012 at 6:43 AM, Alexander Pavlenko <aler...@gmail.com> wrote:
But I want to notice, that column != attribute in common case, for example:

> User.first.update_column :password, '123123'
  SQL (0.2ms)  UPDATE "users" SET "password" = '123123' WHERE "users"."id" = 1
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: password: UPDATE "users" SET "password" = '123123' WHERE "users"."id" 

> User.first.update_attribute :password, '123123'
   (0.4ms)  UPDATE "users" SET "password_digest" = '$2a$10$x3GxNtIEClpqJD1kwGKFneOWh6v9JJbdeb9KW36qN8R2oPdcr/hPG', "updated_at" = '2012-08-09 13:38:53.459408' WHERE "users"."id" = 1

среда, 13 июня 2012 г., 19:37:52 UTC+4 пользователь MikeGehard написал:

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-core/-/6KLIU1Jn2mMJ.

To post to this group, send email to rubyonra...@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-co...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.



--
Andrew Mutz
Director of Software Engineering
AppFolio, Inc.

andre...@appfolio.com
-------------------------------------------------------
Find Us Online -- 
www.AppFolio.com
www.Facebook.com/AppFolio
www.RentApp.com
Reply all
Reply to author
Forward
0 new messages