This project is archived and is in readonly mode.
partial_updates clobbers serialized attributes
-
Ryan Bates
This is a known behavior of dirty tracking. It can't detect changes made directly on an attribute. You have to either go through the accessor method or warn dirty tracking you're changing the attribute.
m.data = {:b=>2, :a=>1} # or m.data_will_change! m.data[:b] = 2See ticket #608 Dirty checking is broken for string join for more info.
-
John Wulff
Prior to dirty tracking changes made to serialized objects were saved. Now they are not. This is the way things are going to stay?
-
Tom Lea
- Tag changed from activerecord, bug to 2.1, activerecord, bug, patch
This looks like a bug to me... with partial_updates update will only save attributes that are dirty, so serialized attributes are skipped.
Trivial quick patch attached to resolve this.
-
Doug Cole
I apologize for criticizing without offering up my own patch, but it seems like this patch lacking a few things. Why not rewrite changed? for serialized attributes that checks the serialization against the old value and stores the results. Then run changed? against all serialized attributes at the beginning of update_with_dirty. It'll be slower, but it will then behave as expected rather than always assuming serialized attributes are changed.
As an aside if this was a known behavior of rails 2.1, it seems like it should have been better publicized. I couldn't find any mention of it even though it breaks nearly every rails app that uses serialized attributes.
-
Tom Lea
It would be nice, but this would make the behaviour inconsistent with the (odd but expected) behaviour of other attributes (see #608 Dirty checking is broken for string join).
The patch will not fix any issues with AR#changed? & family. Just a bug with partial_updates.
If we wished to have a comparison with previous values, we would have to stash the values of all attributes at record load. This would be a very different approach to what is currently there.
But I digress...
The patch makes things save as expected in 2.0, preventing 'mystery' data loss, it does not change the AR#changed? 2.1 features.
-
Doug Cole
yuck. Well thanks for the heads up on #608 Dirty checking is broken for string join and the patch Tom.
-
Tom Lea
- Title changed from Saving Only "changed" Attributes Hurts Serialization to partial_updates clobbers serialized attributes
-
Repository
- State changed from new to committed
(from [992fda16ed662f028700d63a8dcbd1837f1d58ab]) Serialized attributes will now always be saved even with partial_updates turned on.
Signed-off-by: Michael Koziarski michael@koziarski.com [#788 partial_updates clobbers serialized attributes state:committed] http://github.com/rails/rails/co...
-
Repository
(from [decc9730959de85b4c4873986bcd33e12fa1985d]) Serialized attributes will now always be saved even with partial_updates turned on.
Signed-off-by: Michael Koziarski michael@koziarski.com [#788 partial_updates clobbers serialized attributes state:committed] http://github.com/rails/rails/co...
-
Michael Koziarski
Normally I wouldn't like a special case like this, but as 99.9% of the time you're modifying serialized attributes in place.
-
Tom Lea
Thanks for the commit Koz!
-
John Wulff
Thanks Koz.
-
Jérôme
Wow, this is really a critical bug as this buggy behavior breaks applications when the Dirty module was introduced to rails. This patch deserves a minor release and Tom some national honors.
-
Michael Koziarski
We're considering a minor release shortly and this will be included in it.
-
Jérôme
May I hug you ?
-
Steve Purcell
Thank god/Tom/Koz for that. I've just spent a whole day tracking down a bug that was due to this misbehaviour.
-
John Wulff
Sad this isn't in 2.0.4.
-
Jeremy Kemper
John, partial updates were first introduced in 2.1 so backporting this patch wouldn't make sense for 2.0.x.
-
John Wulff
Thanks Jeremy. That was awfully stupid of me.
-
Jeremy Kemper
John, hey no worries :)
I'm not sure why this is marked as committed only, rather than resolved, though. Koz?
-
Michael Koziarski
I've been using committed for all my patches I apply. committed isn't finished?
-
Jérôme
- Tag changed from 2.1, activerecord, bug, patch to 2.1, activerecord, bug, patch
Then sad this isn't in rails 2.1.1 :(
-
Jérôme
Oops sorry it is. Not it the changelog I guess.
-
Michael Koziarski
It is in 2.1.1 isn't it?
-
Fjan
Yes, it is in 2.1.1. I understand the reasoning for marking serialized objects as dirty each save, to be consistent with earlier behaviour. But is there any way to get the old behaviour back? I have a couple of large serialized objects that now get serialized and saved every time...
-
Michael Koziarski
Not presently but if you'd like to submit a patch for it we could apply it
-
Fjan
Ok, I looked at the code and it seems relatively straightforward to add support for something like:
ActiveRecord::Base.partial_updates = false | true | :serialized_also
Should be about 3 lines of code which seems a pretty worthwhile effort to avoid expensive serializing. But I'm afraid I'm not very experienced (I've yet to submit a patch for anything) so I'm going to defer that until I have a rainy afternoon to figure out that whole git and diff thing. Unless someone else wants to take up the glove a monkey patch will do for now.
