This project is archived and is in readonly mode.
Nested objects don't deserialize completely (Rails 3 beta 4)
-
Stefan Siebel
- Title changed from Nested objects don't deserialized completely (Rails 3 beta 4) to Nested objects don't deserialize completely (Rails 3 beta 4)
-
Aaron Patterson
- Assigned user set to Aaron Patterson
- Importance changed from to Low
Could you possibly upload an app that has this error (and a test)? I'd like to take a look.
-
Stefan Siebel
Hi Aaron,
cool, thank you! Please see attached file. It looks like the issue is a little bit weird. I tried to reproduce it with a test, but apparently the test works fine.
That's how you can reproduce the issue:
1) Create a new user object through the UI (localhost:3000/users)
2) load the rails console, type in:u = User.last u.preferences.test.kind_of? Something => falseAnother to reproduce it, only with rails console, without web UI:
a = User.new a.save b = User.last b.preferences.test.kind_of? Something => true reload! b = User.last b.preferences.test.kind_of? Something => falseDoes that help?
-Stefan
-
Aaron Patterson
- Tag changed from activerecord rails3, serialize to activerecord rails3, serialize, yaml
- State changed from new to invalid
Hey Stefan!
Thanks for the sample application! I was indeed able to reproduce the problem, but unfortunately the problem isn't from Rails. I'll show you the fix for your code, then go in to detail about the problem.
Just add this to the top of your photo_style.rb file:
require 'style_element'The problem is that your class isn't defined at the time the YAML gets deserialized. You've taught Rails how to load the top level constant when you made the
serialize :preferences, UserPreferencescall. Unfortunately, it doesn't know how to load the other class. We can reproduce this behavior with a Ruby program like this:require 'yaml' class UserPreferences end p YAML.load DATA.read __END__ --- !ruby/object:UserPreferences test: !ruby/object:Something a: 1 b: 2 c: 3You'll note that the output of this shows the same problem that the rails code is experiencing. If you were using Marshal to serialize and deserialize these objects, this case would actually result in an exception being raised. The reason an exception is raised with marshal is because it doesn't know the definition of that object, so it can't properly deserialize it.
I believe this difference between Marshal and YAML to be a bug. The newer YAML parser in ruby 1.9 (psych) will raise an exception in this case, matching the behavior of Marshal. For example:
require 'yaml' YAML::ENGINE.yamler = 'psych' class UserPreferences end p YAML.load DATA.read __END__ --- !ruby/object:UserPreferences test: !ruby/object:Something a: 1 b: 2 c: 3If you run the above code using Ruby 1.9.2 you'll see the exception raised. That exception can give rails a chance to load the missing constant.
I hope this explanation helps!
-
Stefan Siebel
Excellent Aaron! Thank you!
I already sort of expected it's something I'm doing wrong since I'm still pretty new to Ruby / Rails :-)
Thanks again, I really appreciate!
-Stefan.
