Rails partial updates problem with hashes
Asked Answered
S

1

1

Rails ActiveRecord support partial updates and it works well most of the time, but in case we have serialized hash field AR executes update every time, even if nothing has been changed. Here example from rails console:

### Create class and table ###
>> class Xx < ActiveRecord::Base; serialize :params; end
=> Object 

>> ActiveRecord::Base.connection.execute "CREATE TABLE xxes(id serial, params text)"
SQL (43.8ms)  CREATE TABLE xxes(id serial, params text)
=> #<PGresult:0x112113380>


### Create record ###
>> r = Xx.create(:params => {:a => 1})
SQL (0.9ms)  INSERT INTO "xxes" ("params") VALUES ('--- 
:a: 1
') RETURNING "id"
=> #<Xx id: 1, params: {:a=>1}>


### Find this record ### 
>> x = Xx.find(1)
Xx Load (2.5ms)  SELECT "xxes".* FROM "xxes" WHERE "xxes"."id" = 1 LIMIT 1
=> #<Xx id: 1, params: {:a=>1}>


### Change nothing and call save ###
>> x.save
AREL (1.1ms)  UPDATE "xxes" SET "params" = '--- 
 :a: 1
' WHERE "xxes"."id" = 1
=> true 

Are there any workaround?

Silage answered 16/9, 2011 at 17:1 Comment(0)
A
1

x.save if x.changed?

http://ar.rubyonrails.org/classes/ActiveRecord/Dirty.html

Amberlyamberoid answered 16/9, 2011 at 17:12 Comment(5)
It will work only in simple cases when we have only one field. But what if we have one field more and this second field really changed, but params - doesn't. It will add 'param' to update anywaySilage
I don't understand why that would be badAmberlyamberoid
Intention of partial updates is to minimize unnecessary database writes. And with hashes/serialize it doesn't happens.Silage
if you're updating the row it shouldn't make any difference how many columns you write.Amberlyamberoid
For most databases (postgres for example postgresql.org/docs/9.1/static/storage-toast.html) dynamic size columns like texts stored in separate place from fixed size columns. So updating 'integer' and 'text' columns will be about two times slower (at least in some cases) then updating just integer.Silage

© 2022 - 2024 — McMap. All rights reserved.