While upgrading an app to 2.2.1 I noticed a change in the behavior of serialized attributes in ActiveRecord. I have an AR model with a serialized attribute which is used to store either a fixnum of an array of fixnums. Previously, a single fixnum stored in this attribute would be returned as a fixnum, however since a recent commit [1] it is now returned as a string. I''m not sure whether is a typical use case, but it doesn''t seem like expected behavior. I started looking at creating a patch but it became non-trivial as I strayed off into ActiveRecord::ConnectionAdapters::Quoting. So instead, I thought it better I get some feedback here. Cheers, Paul [1] http://github.com/rails/rails/commit/c94ba8150a726da4a894cd8325ee682a3286ec9f --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---
Michael Koziarski
2008-Nov-19 17:32 UTC
Re: Change in the behavior of serialized attributes
> While upgrading an app to 2.2.1 I noticed a change in the behavior of > serialized attributes in ActiveRecord. > > I have an AR model with a serialized attribute which is used to store either > a fixnum of an array of fixnums. Previously, a single fixnum stored in this > attribute would be returned as a fixnum, however since a recent commit [1] > it is now returned as a string. > > I''m not sure whether is a typical use case, but it doesn''t seem like > expected behavior. I started looking at creating a patch but it became > non-trivial as I strayed off into ActiveRecord::ConnectionAdapters::Quoting. > So instead, I thought it better I get some feedback here.Seems like this should function correctly:>> YAML.dump(1)=> "--- 1\n" I assume the database column is ending up with a literal "1" in it, without the yaml prefix? If so, does overwriting your setter method fix that for you? def whatever=(v) write_attribute(:whatever, YAML.dump(v)) end> Cheers, > Paul > > [1] > http://github.com/rails/rails/commit/c94ba8150a726da4a894cd8325ee682a3286ec9f > > > >-- Cheers Koz --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---
> > I assume the database column is ending up with a literal "1" in it, > without the yaml prefix? >Yeah, exactly. If so, does overwriting your setter method> fix that for you? >My immediate reaction was that it would, I was thinking along the same lines earlier. I''ve just tried it though, and I still end up with a literal "1" in the database. If I take the call to serialize out of the model, the overwritten setter does as you''d expect and I do end up with YAML in the db. I''ve done a bit of digging and here''s what I _think_ is happening. Before the save happens, each attribute is quoted by attributes_with_quotes, and attributes_with_quotes uses read_attribute to fetch the value of each attribute. But, within read_attribute there is a call to unserialize_attribute (for serialized columns only) and hence we end up back where we started. Cheers, Paul On Wed, Nov 19, 2008 at 5:32 PM, Michael Koziarski <michael@koziarski.com>wrote:> > > While upgrading an app to 2.2.1 I noticed a change in the behavior of > > serialized attributes in ActiveRecord. > > > > I have an AR model with a serialized attribute which is used to store > either > > a fixnum of an array of fixnums. Previously, a single fixnum stored in > this > > attribute would be returned as a fixnum, however since a recent commit > [1] > > it is now returned as a string. > > > > I''m not sure whether is a typical use case, but it doesn''t seem like > > expected behavior. I started looking at creating a patch but it became > > non-trivial as I strayed off into > ActiveRecord::ConnectionAdapters::Quoting. > > So instead, I thought it better I get some feedback here. > > Seems like this should function correctly: > > >> YAML.dump(1) > => "--- 1\n" > > I assume the database column is ending up with a literal "1" in it, > without the yaml prefix? If so, does overwriting your setter method > fix that for you? > > def whatever=(v) > write_attribute(:whatever, YAML.dump(v)) > end > > > > Cheers, > > Paul > > > > [1] > > > http://github.com/rails/rails/commit/c94ba8150a726da4a894cd8325ee682a3286ec9f > > > > > > > > > > > -- > Cheers > > Koz > > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---
Michael Koziarski
2008-Dec-01 19:07 UTC
Re: Change in the behavior of serialized attributes
> My immediate reaction was that it would, I was thinking along the same lines > earlier. I''ve just tried it though, and I still end up with a literal "1" in > the database. If I take the call to serialize out of the model, the > overwritten setter does as you''d expect and I do end up with YAML in the db. > > I''ve done a bit of digging and here''s what I _think_ is happening. Before > the save happens, each attribute is quoted by attributes_with_quotes, and > attributes_with_quotes uses read_attribute to fetch the value of each > attribute. But, within read_attribute there is a call to > unserialize_attribute (for serialized columns only) and hence we end up back > where we started.Sorry this took so long. Conferences and projects lead to less mailing list time. We already have special code in there for serialized Date and Time classes, so why not try something like: http://pastie.caboo.se/327995 That causes two tests to fail simply because they''re testing on uniqueness of a serialized field while not storing serialized fields in the database. -- Cheers Koz --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---
> > Sorry this took so long. >No worries. I ended up over writing both the getting and the setting in the app since I was relying on another subtle aspect of the behavior which I think changed. so why not try something like: Makes sense. I''m hoping to come back and have another look at this when I get chance, I''ll let you know when I do. Cheers, Paul --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en -~----------~----~----~----~------~----~------~--~---