Updating only changed columns in ActiveRecord

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
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')

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.



This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs