# Updating only changed columns in ActiveRecord

**URL:** <https://www.ruby-forum.com/t/updating-only-changed-columns-in-activerecord/103066>\
**Category:** Rails\
**Created:** [May 1, 2007, 12:29pm UTC](https://www.ruby-forum.com/t/updating-only-changed-columns-in-activerecord/103066 "2007-05-01T12:29:48Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![candlerb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/c5a1d2/32.png) [@candlerb](https://www.ruby-forum.com/u/candlerb)\
**Post date:** [May 1, 2007, 12:29pm UTC](https://www.ruby-forum.com/t/updating-only-changed-columns-in-activerecord/103066/1 "2007-05-01T12:29:48Z")

</div>

Does anyone know of a way to get ActiveRecord to update only the  
columns which have changed? For example, consider a table foos with  
columns x,y,z. If I do

```
f = Foo.find(123)
f.update_attributes(:x => 99)

```

then I want AR to generate

```
UPDATE foos SET x=99 WHERE id=123

```

rather than what it currently does:

```
UPDATE foos SET x=99, y=2, z=3 WHERE id=123

```

(assuming y=2 and z=3 were the values read in by Foo.find)

Why do I want this? Well, I have tables which are updated  
asynchronously due to external events, as well as by the user looking  
at the record in Rails. Both the frontend and the event-handling  
backend are using ActiveRecord. There are some fields which are  
updated by the operator, and others which are updated by the backend.  
But using ActiveRecord, there’s a race condition between reading a row  
and writing it back out again, which means that changes made by the  
other party may be lost.

I searched for a plugin at  
[http://agilewebdevelopment.com/plugins/search?search=update](http://agilewebdevelopment.com/plugins/search?search=update)  
but couldn’t find anything relevant.

So, the options I can think of are:

(1) Bypass ActiveRecord’s ‘save’ and ‘update’ methods entirely

```
f = Foo.find(123)
... compare f with params, determine that only 'x' has changed
Foo.update_all(['x=?',params[:foo][:x]], ['id=?',123])

```

But this has to be done consistently everywhere. I guess I can write  
my own version of update\_attributes which does this.

(2) Read each record twice:

```
f1 = Foo.find(123)
... compare f1 with params, determine that only 'x' has changed
f2 = Foo.find(123, :select => 'x')
f2.update_attributes(params[:foo])

```

This seems like unnecessary overhead.

I had a quick look through the code path for ‘update\_attributes’ but  
it seems to be intimately bound to ‘save’, and ‘save’ seems to have no  
concept of which attributes have changed.

Thanks for any suggestions.

Regards,

Brian.
