sticking your models into cache, or serializing them for other reasons shouldn't be painful. unfortunately it is with most ORMs, as they have a lame marshal strategy by default. however this is easy to fix: they key lies in understanding that every ORM already knows how to take a hash of info from the db and instantiate a full blown instance. knowing this, we can easily make any model serialize like butter.
#! /usr/bin/env ruby
# some models have whack shit that can't survive a marshal round-trip
#
class Model
include Mongoid::Document
def initialize(*args, &block)
super
ensure
@fail = Class.new, open(__FILE__)
end
end
# so this'll fail
#
begin
p Marshal.load(Marshal.dump(Model.create))
rescue Object => o
warn "#{ o.message } (#{ o.class })"
end
# but mongoid models simply need a hash of information from the mongo driver
# to fully vivify themselves... ergo this is all we need persist when
# marshaled. this makes loading from marshaled data *just like* loading from
# the db.
#
# if you ask me this should be the default behavior!
#
# hrm - i am on mongoid core... @durran, what do you think?
#
# btw - this works just fine with active_record too...
#
class Model
def _dump(*args, &block)
Marshal.dump(raw_attributes, *args, &block)
end
def Model._load(string, *args, &block)
raw_attributes = Marshal.load(string, *args, &block)
instantiate(raw_attributes)
end
end
# so now it just werks (TM)
#
p Marshal.load(Marshal.dump(Model.create))
BEGIN {
require 'rubygems'
require 'mongoid'
Mongoid.configure{|config| config.connect_to('mongoid-marshal')}
}
__END__
teh outputz:
can't dump anonymous class #<Class:0x007fa89dc23768> (TypeError)
#<Model _id: 5130edd0af481ccd3d000002, >
ref: https://gist.github.com/ahoward/5066528
Tweet