Skip to content


Subversion checkout URL

You can clone with
Download ZIP


YAML can't properly deserialize Mongoid instances with embedded objects #187

scottburton11 opened this Issue · 4 comments

6 participants


Here's something I noticed working with Delayed Job and Mongoid instances, and I believe it fits into the "YAML can't deserialize this" camp, for whatever reason.

When I have a class with embedded documents and create a delayed job in a callback of any kind, I wind up with a handler that YAML can't deserialize:

class Foobatz
 include Mongoid::Document
 field :name, :type => String
 before_save :do_something_awesome_later

 embeds_many :monkey_beavers

 def do_something_awesome_later


 def do_something_awesome
   # Something awesome happens here


class MonkeyBeaver
 include Mongoid::Document
 field :name, :type => String
 field :size, :type => String

 embedded_in :foobatz, :inverse_of => :monkey_beavers

Calling #do_something_awesome_later on an object right out of the database works fine:

f  = Foobatz.last
=> #<Foobatz _id: 4d2a561c44939bb67f000001, name: "Horkable", awesome: true> 
=> #<Delayed::Backend::ActiveRecord::Job id: 812, priority: 0, attempts: 0, handler: "--- !ruby/struct:Delayed::PerformableMethod \nobject...", last_error: nil, run_at: "2011-01-10 01:00:40", locked_at: nil, failed_at: nil, locked_by: nil, created_at: "2011-01-10 01:00:40", updated_at: "2011-01-10 01:00:40"> 
=> #<struct Delayed::PerformableMethod object=#<Foobatz _id: 4d2a561c44939bb67f000001, name: "Horkable", awesome: true>, method_name=:do_something_awesome, args=[]> 

but creating the job using the #before_save callback adds something to the serialized job handler that YAML can't handle:
=> true 
Delayed::DeserializationError: Job failed to load: uninitialized constant Syck::Syck. Handler: "--- !ruby/struct:Delayed::PerformableMethod \nobject: &id002 !ruby/object:Foobatz \n  accessed: {}\n\n  attributes: \n    _id: !ruby/object:BSON::ObjectId \n      data: \n      - 77\n      - 42\n      - 86\n      - 28\n      - 68\n      - 147\n      - 155\n      - 182\n      - 127\n      - 0\n      - 0\n      - 1\n    awesome: true\n    monkey_beavers: \n    - !map:BSON::OrderedHash \n      _id: &id001 !ruby/object:BSON::ObjectId \n        data: \n        - 77\n        - 42\n        - 86\n        - 68\n        - 68\n        - 147\n        - 155\n        - 182\n        - 127\n        - 0\n        - 0\n        - 2\n      name: Clarance\n      size: \"22\"\n    name: Horkable\n  errors: !omap []\n\n  modifications: {}\n\n  monkey_beavers: \n  - !ruby/object:MonkeyBeaver \n    _index: 0\n    _parent: *id002\n    accessed: {}\n\n    attributes: \n      _id: *id001\n      name: Clarance\n      size: \"22\"\n    errors: !omap []\n\n    metadata: !map:Mongoid::Relations::Metadata \n      :relation: !ruby/class Mongoid::Relations::Embedded::Many\n      :extend: \n      :inverse_class_name: Foobatz\n      :name: :monkey_beavers\n    modifications: {}\n\n    previous_modifications: {}\n\n    validation_context: \n  previous_modifications: {}\n\n  validation_context: \nmethod_name: :do_something_awesome\nargs: []\n\n"
from /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/delayed_job-2.1.2/lib/delayed/backend/base.rb:77:in 'rescue in payload_object'
from /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/delayed_job-2.1.2/lib/delayed/backend/base.rb:75:in 'payload_object'
from (irb):8
from /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/railties-3.0.3/lib/rails/commands/console.rb:44:in 'start'
from /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/railties-3.0.3/lib/rails/commands/console.rb:8:in 'start'
from /Users/scott/.rvm/gems/ruby-1.9.2-p0/gems/railties-3.0.3/lib/rails/commands.rb:23:in '<top (required)>'
from script/rails:6:in 'require'
from script/rails:6:in '<main>'

I'm not entirely sure what Syck has to do with it. Incidentally, if the object instead has a relation, or a memoized method, DelayedJob rescues a different error:
Delayed::DeserializationError: Job failed to load: undefined method `fields' for nil:NilClass.

The YAML-ized handler in the failing (callback-initiated) version has a BSON::OrderedHash for the embedded collection.

I know these are YAML issues, not DelayedJob issues, but I'm curious to know if I can implement a callback-initiated job in some other way. One alternative was to simply re-instantiate the object (using #find, for example) - in which case the handler YAML doesn't contain a reference to the embedded collection or anything else fishy - but I don't like having to resort to the extra queries.

Any ideas?


I also faced the same problem. Did you found any workaround for it?


I have the same for the Couchrest casted properties.


You need to override the find method of your embedded document to helps DelayedJob to deserialize it.
You can use this gist, which also supports multiple nesting of documents:


I had the same problem – @cblavier’s gist solved it for me. Any chance of getting that merged into delayed_job or delayed_job_mongoid?

@albus522 albus522 closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.