This project is archived and is in readonly mode.
Supporting partial updates for serialized columns
-
ronin-37814 (at lighthouseapp)
- Tag changed from activerecord to activerecord, attributes, dirty, partial, serialized, updates
fixed bug with nils; updated tests
-
chris finne
Still studying the code (as I could use this functionality as well on my current app), but shouldn't this:
-
return val if val.is_a? String and val =~ /^---/
be more like:
-
return val if val.is_a? String and val =~ /\A---/
-
-
ronin-37814 (at lighthouseapp)
wow glad someone is actually looking at this :)
Yes, I believe you are right that is more correct... the one I used I pulled right out of base.rb:
def object_from_yaml(string) return string unless string.is_a?(String) && string =~ /^---/ YAML::load(string) rescue string endBut that would match "abcd\n---" so that's bad, thanks for pointing this out.
-
Michael Koziarski
- State changed from new to wontfix
I'm not sure I like doing this, my preference would be to provide an API to allow users to mark an attribute as dirty rather than comparing the yaml strings. That way people could implement their own functionality to figure this out if they want to.
something as simple as mark_dirty :some_serialized_attribute would enable this for those who need it, without the complexity and cost being paid by every other user.
-
ronin-37814 (at lighthouseapp)
Hey Koz,
Thanks for responding to this ticket. So I totally understand not wanting to pay the perf penalty for this.
Would you be opposed to a solution which almost has no perf impact on people who don't care for the feature? For example you call a class method like, track_dirty :some_serialized_attribute, which then compiles the method(s) which do the necessary yaml comparisons. If the user doesn't invoke this feature then the method remains a no-op and they pay almost no perf penalty.
-
Michael Koziarski
An API which would let you explicitly mark a column as dirty would let
you achive this with an after_find and a before_save. So that's the
right option I think. -
ronin-37814 (at lighthouseapp)
So, we already have the will_change! API. But at some point (i forget what version) you stopped requiring this for serialized attributes and just always saved them, since you guys, I guess, decided you didn't want people to have to hit will_change! every time they touched a serialized attribute.
So are you suggesting to have some option which maybe reverts the behavior to the original which will then require will_change! every time you touch a serialized attribute? Or some class method which reverts the behavior on an attribute-by-attribute basis?
I still prefer having rails handle this automatically for me if I tell it to. I think the reason you guys probably removed the partial updates for serialized attributes originally was because no one realized/remembered to call will_change! every time they touched it. I think this can probably be achieved with very little overhead for people who decide not to use it.
What do you think?
-
Michael Koziarski
I think the best option is to add an option (per class) which says
whether or not to support partial updates with serialized attributes.
Currently we don't allow you to do that at all, we just always save
them. That combined with will_change! will let people opt-in to the
dirty tracking that you're after here.Whereas the majority of users can just stick with the defaults and
always save them, people will be able to mark things as dirty using
their own custom accessors. seems like a good win. -
ronin-37814 (at lighthouseapp)
Yea I agree that is better than what we have now. But I am more interested in getting serialized attr updates for free. Having to call will_change! every time you update a hash or array index is quite error prone. If it could be done on an opt-in (even per-attr) basis w/o a perf penalty to those who don't opt-in, would you be opposed?
-
Michael Koziarski
Yeah, I'm kinda opposed to making those kind of changes, but would be
happy to look at a patch which achieved it.Fundamentally if you're directly working with serialized objects (i.e.
without encapsulation) then you'll have problems.If you're doing it with encapsulation, then there's no difficulties at all.
