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.

After update to Rails 3.0.0 release, serialization seems to be broken?

#5525

I updated my application to Rails 3.0.0 and noticed something I don't totally understand.

You can find the application here http://github.com/Skarabaeus/PhotoYear/tree/master/app/models

In Photo.rb I have code like this:

class Photo < ActiveRecord::Base
  serialize :style, PhotoStyle
  [...]
end

Before the update to Rails 3 what I saw in the data base was e.g.:

--- !ruby/object:PhotoStyle
a: !ruby/object:StyleElement 
  selector: a
  style: 
    color: "#858585"
body: !ruby/object:StyleElement 
  selector: body
  style: 
    background-color: "#000"
    color: "#d1d3eb"
theimage: !ruby/object:StyleElement 
  selector: "#theimage"
  style: 
    border: "0"
    box-shadow: "1px 3px 15px [#555](/projects/8994/tickets/555 "Ticket #555")"

Now, when I create a new Photo or update an existing one, I see:

#<PhotoStyle:0xb6e127b8>

When I try to load such a record I am getting an exception:

"style was supposed to be a PhotoStyle, but was a String. "

I checked the Rails 3 release notes, but didn't notice anything about the serialize method except "ActiveSupport::OrderedHash now can de-serialize through YAML."

I totally might be I'm overseeing something here. Any idea what?

Thanks!

Reported by Stefan Siebel · September 1st, 2010 @ 10:27 PM

State: resolved
Milestone: 3.0.2
Assigned to: nobody
Importance: Low

Activity

  1. Stefan Siebel
    Stefan Siebel

    H Aaron, I set you as "who is responsible" because you helped me last time with it :-) (#5002 Nested objects don't deserialize completely (Rails 3 beta 4). I hope it's not yet another thing I didn't get right!

    September 1st, 2010 @ 10:29 PM

  2. Neeraj Singh
    Neeraj Singh
    • State changed from new to needs-more-info
    • Importance changed from to Low

    I am not able to reproduce it.

    This is what I did with rails 2.3.8

    class User < ActiveRecord::Base
      serialize :data
    end
    
    >> u = User.first
    >> u.data = {:foo => :bar}
    => {:foo=>:bar}
    
    # the sql was
    UPDATE `users` SET `updated_at` = '2010-09-02 04:31:35', `data` = '--- \n:foo: :bar\n' WHERE `id` = 1
    

    Then I switched to rails edge. I used mysql database to do this test.

    > u = User.first
    > u.data
      => {:foo=>:bar}
    

    As you can see data looks fine to me.

    I added just simple hash. I would suggest you to add more complex data structure incrementally and then see if it fails for some case. Once I had an issue with openstruct. The yaml could not be deserialized.

    September 2nd, 2010 @ 05:38 AM

  3. Stefan Siebel
    Stefan Siebel

    Hi Neeraj, thank you for your answer. Using a Hash indeed works. I attached a minimum example which reproduces the error for me. I am using Ruby 1.8.7 and Rails 3.0.0.

    In user_test.rb I added a test like this:

    test "try to save a User and load it" do
      a = User.new
      a.pref = MyClass.new
      a.save!
    
      b = User.last
    
      assert b.pref.class == 'MyClass'
    end
    

    When running the test I get:

    Loaded suite unit/user_test
    Started
    E
    Finished in 0.181865 seconds.
    
    1) Error:
    test_try_to_save_a_User_and_load_it(UserTest):
    ActiveRecord::SerializationTypeMismatch: pref was supposed to be a MyClass, but was a String
    
    
    1 tests, 0 assertions, 0 failures, 1 errors
    

    I am on vacation for the next two weeks and don't really have internet access for this time. So my next replay to this ticket might take a while ;-)

    September 2nd, 2010 @ 03:37 PM

  4. Santiago Pastorino
    Santiago Pastorino
    • Milestone cleared.
    • State changed from needs-more-info to open

    September 5th, 2010 @ 02:02 AM

  5. reaper
    reaper

    +1 for me.

    I'm using the exifr gem to pull exif data from images and then store that info in the database. I have exactly the same problem where it appears my object is being run through to_str instead of to_yaml before getting stored in the database (so all entries end up looking like the following):

    #<EXIFR::JPEG:0x00000107118a70>
    
    Personally I think this should be a higher priority than Low since it worked before, but is actually silently failing now. Entries end up in the database, but the data isn't really there. Anyone using this to store any kind of important data (like IPN responses from a payment gateway, etc) will be in for a rude awakening when they go to access the data and find all they have is garbage.

    September 5th, 2010 @ 12:37 PM

  6. Repository
  7. Repository
  8. MarianTheisen
    MarianTheisen
    • Assigned user cleared.

    ran into this bug today, extremely dirty workaround:

    since serialization for Hash, Array etc is working, wrap your attribute in an array

    class Order < ActiveRecord
      serialize :items


    def items= items

    write_attribute :items, [items]
    
    
    
    
    end
    def items
    read_attribute(:items).first
    
    
    
    
    end end

    October 7th, 2010 @ 01:52 PM

  9. Jeremy Kemper
  10. Ivo Wever
    Ivo Wever

    The linked patch alone does not seem enough to solve this issue: I've create a patched version of 3.0.1 with those patches applied and the serialization still fails.
    Failing spec:

        it "should serialize the output to YAML when stored (issue 2196)" do

      class MyCustomClass
      end
      impl_output.output = MyCustomClass.new
      impl_output.save!
      impl_output.reload
      impl_output.output_before_type_cast.should ==
          &quot;--- !ruby/object:MyCustomClass {}\n\n&quot;
    end</code>
    
    
    
    

    November 9th, 2010 @ 02:00 PM

  11. Ivo Wever
    Ivo Wever

    Sorry, I retract my previous comment: I just verified that the fix works just fine.

    November 9th, 2010 @ 02:29 PM