This project is archived and is in readonly mode.

#2764 ✓wontfix
ronin-37814 (at lighthouseapp)

Supporting partial updates for serialized columns

Reported by ronin-37814 (at lighthouseapp) | June 5th, 2009 @ 02:43 AM | in 2.x

This is my first pass at supporting partial updates for serialized columns.

The fact that serialized columns are always saved, regardless of whether they have changed, led to data clobbering issues in my production app.

Looking for some feedback on this.

Comments and changes to this ticket

  • ronin-37814 (at lighthouseapp)

    ronin-37814 (at lighthouseapp) June 5th, 2009 @ 02:59 AM

    • Tag changed from activerecord to activerecord, attributes, dirty, partial, serialized, updates

    fixed bug with nils; updated tests

  • chris finne

    chris finne June 19th, 2009 @ 10:18 AM

    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)

    ronin-37814 (at lighthouseapp) June 19th, 2009 @ 10:30 AM

    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
      end
    

    But that would match "abcd\n---" so that's bad, thanks for pointing this out.

  • Michael Koziarski

    Michael Koziarski June 26th, 2009 @ 06:23 AM

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

    ronin-37814 (at lighthouseapp) June 26th, 2009 @ 09:49 AM

    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

    Michael Koziarski June 27th, 2009 @ 06:22 PM

    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)

    ronin-37814 (at lighthouseapp) June 29th, 2009 @ 07:09 PM

    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

    Michael Koziarski June 30th, 2009 @ 03:23 AM

    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)

    ronin-37814 (at lighthouseapp) June 30th, 2009 @ 04:34 PM

    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

    Michael Koziarski July 5th, 2009 @ 04:58 AM

    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.

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>

Referenced by

Pages