Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Serialized Fixnum, Float or Boolean returns a String after save

#1379

Using the included code under Rails 2.2 RC1 or lower to serialize an attribute, if you set the value to be a Fixnum it will be returned back to you as a Fixnum.


Loading development environment (Rails 2.2.0)
>> AppVariable.set('test_fixnum', 5)
AppVariable.set('test_fixnum', 5)
=> true
>> AppVariable.get('test_fixnum')
AppVariable.get('test_fixnum')
=> 5
>>

Under Rails 2.2 RC2 the returned value is a String when it should be a Fixnum.


Loading development environment (Rails 2.2.1)
>> AppVariable.set('test_fixnum', 5)
AppVariable.set('test_fixnum', 5)
=> true
>> AppVariable.get('test_fixnum')
AppVariable.get('test_fixnum')
=> "5"
>>

# Table name: app_variables
#
#  id         :integer(4)      not null, primary key
#  name       :string(255)
#  value      :text
#

class AppVariable < ActiveRecord::Base

  serialize :value

  def self.set(name, value)
    record = self.find_or_create_by_name(name.to_s)
    record.value = value
    record.save
  end

  def self.get(name)
    self.find_or_initialize_by_name(name.to_s).value
  end
end

Reported by asrux · November 15th, 2008 @ 09:35 AM

State: stale
Milestone: 2.x
Assigned to: Michael Koziarski Michael Koziarski
Importance: none

Activity

  1. DHH
    DHH
    • Milestone cleared.

    November 15th, 2008 @ 03:33 PM

  2. Michael Koziarski
  3. asrux
    asrux
    • Title changed from Serialized Fixnum returns a String after save to Serialized Fixnum, Float or Boolean returns a String after save

    I tested this with a few other data types and found that the same thing happens with floats and booleans as well, booleans aren't returned correctly under RC1 either, they come back as an integer instead of a boolean, under RC2 and later it's a string representation of the integer.

    It appears that the data isn't being stored in the database in yaml format for simple data types. only more complex data types like hashes are stored as yaml.

    November 22nd, 2008 @ 12:44 PM

  4. Michael Koziarski
    Michael Koziarski
    • Assigned user changed from DHH to Michael Koziarski

    I think the fix should look something a bit like this?

    http://pastie.caboo.se/327995

    The change causes test failures because the Topic model serializes content Any comments / suggestions?

    December 1st, 2008 @ 07:19 PM

  5. asrux
    asrux

    That fix seems to work for this problem, but i can see it being a problem with values that are nil or false, both nil and false can be converted to yaml and brought back but they wouldn't be serialized.

    Maybe something like this would be better:

    We need explicit to_yaml because quote() does not properly convert Time/Date fields to YAML.

    if self.class.serialized_attributes.has_key?(name) value = value.to_yaml elsif value && self.class.serialized_attributes.has_key?(name) && (value.acts_like?(:date) || value.acts_like?(:time)) value = value.to_yaml end

    I can't get the rails unit tests to run on either of my machines (under windows) so i'm not sure what effect that change would have on the unit tests but it should mean that all attributes that are set to be serialized will be regardless of thier value and the other checks will also still run.

    December 6th, 2008 @ 05:36 AM

  6. asrux
    asrux

    Here's the code better formatted (hopefully)

    
                # We need explicit to_yaml because quote() does not properly convert Time/Date fields to YAML.
                if self.class.serialized_attributes.has_key?(name)
                  value = value.to_yaml
                elsif value && self.class.serialized_attributes.has_key?(name) && (value.acts_like?(:date) || value.acts_like?(:time))
                  value = value.to_yaml
                end
    

    December 6th, 2008 @ 05:39 AM

  7. Michael Koziarski
    Michael Koziarski

    Is that nil / false behaviour a regression over what we had in 2.1?

    I think most people who set something to nil would probably expect there to be a NULL in the database rather than "--- \n"

    December 10th, 2008 @ 07:01 PM

  8. Michael Koziarski
    Michael Koziarski
    • State changed from new to stale
    • Milestone set to 2.x

    June 9th, 2009 @ 08:40 AM

  9. Chris Tucker
    Chris Tucker

    What was the motivation for marking this stale? It doesn't look like the issue has been addressed, and continues to cause problems. For reference, it looks like the fix to the following ticket caused this regression:
    #857 Serialized attribute values "Yes" or "No" get coerced into booleans
    The corresponding commit:
    http://github.com/rails/rails/commit/c94ba8150a726da4a894cd8325ee68...
    However, the change there was arguably correct -- it just uncovered a problem in the serialization step (by tightening up the rules on the deserialization step).

    July 29th, 2009 @ 05:55 PM

  10. Michael Koziarski
    Michael Koziarski

    The sole motivation for marking it stale was 6 months without a change / response.

    If you feel like picking up the ball and running with it I'm happy to reopen it for you

    August 1st, 2009 @ 09:23 AM

  11. Chris Tucker
    Chris Tucker

    Patch attached. Fix is simply a case of removing check to see if the value acts like a date or time -- we want to yamlize regardless. A test case is also included, though has not been (ahem) tested as my environment is in a remarkably unhappy place right now.

    August 5th, 2009 @ 04:43 PM

  12. Chris Tucker
    Chris Tucker

    Reviewing your comment from Dec. 1st it looks like this may cause other issues. For my use cases of serialization the patch works well, but it sounds like there are ways in which serialization is used that sit outside of those use cases. Does this mean there are cases where we would not expect YAML to appear in the DB for a serialized attribute?

    August 5th, 2009 @ 04:51 PM