Autoloading Classes when Deserializing YAML Objects (or, What Is This YAML::Object?)
Rails will automatically load Ruby files from your /app, /lib, and other directories when you use the appropriately named constant. For example, if you use the name RailsExampleObject
in your code, Rails will automatically look for a file called rails_example_object.rb and load it.
However, this autoloading of classes fails when deserializing objects from YAML. This can occur, for example, when reading an ActiveRecord object that has a serialize column. So, for example, say you read an ActiveRecord object from a database, and the object has a serialized column that contains an object of type RailsExampleObject
. If the file rails_example_object.rb is not already loaded, then the YAML deserializer will give you a default object of type YAML::Object.
The way to solve this is to instruct the YAML deserializer to autoload classes the same way that Rails does. The following code seems to work for me to do this:
I wrote this code a long time ago, so I don’t know anymore why it works. But it does seem to work.YAML::Syck::Resolver.class_eval do def transfer_with_autoload(type, val) match = type.match(/object:(\w+(?:::\w+)*)/) match && match[1].constantize transfer_without_autoload(type, val) end alias_method_chain :transfer, :autoload end