polleverywhere/quebert

View on GitHub
lib/quebert/serializer.rb

Summary

Maintainability
A
0 mins
Test Coverage
module Quebert
  module Serializer

    # Does this mean you could queue a job that could queue a job? Whoa!
    class Job
      def self.serialize(job)
        {
          'job' => job.class.name,
          'args' => serialize_args(job.args),
          'priority' => job.priority,
          'delay' => job.delay,
          'ttr' => job.ttr,
          'queue' => job.queue
        }
      end

      def self.deserialize(hash)
        hash = Support.stringify_keys(hash)
        job = Support.constantize(hash['job']).new(*deserialize_args(hash['args']))
        job.priority = hash['priority']
        job.delay = hash['delay']
        job.ttr = hash['ttr']
        job.queue = hash['queue']
        job
      end

    private

      # Reflect on each arg and see if it has a seralizer
      def self.serialize_args(args)
        args.map do |arg|
          hash = Hash.new
          if serializer = Quebert.serializers[arg.class]
            hash['serializer'] = serializer.name
            hash['payload'] = serializer.serialize(arg)
          else
            hash['payload'] = arg
          end
          hash
        end
      end

      # Find a serializer and/or push out a value
      def self.deserialize_args(args)
        args.map do |arg|
          arg = Support.stringify_keys(arg)
          if arg.key? 'serializer' and serializer = Support.constantize(arg['serializer'])
            serializer.deserialize(arg['payload'])
          else
            arg['payload']
          end
        end
      end
    end

    # Deal with converting an AR to/from a hash that we can send over the wire.
    class ActiveRecord
      def self.serialize(record)
        attrs = record.attributes.inject({}) do |hash, (attr, val)|
          hash[attr] = val
          hash
        end
        { 'model' => record.class.model_name.to_s, 'attributes' => attrs }
      end

      def self.deserialize(hash)
        hash = Support.stringify_keys(hash)
        model = Support.constantize(hash.delete('model'))
        if attrs = Support.stringify_keys(hash.delete('attributes'))
          if id = attrs.delete('id')
            # This has been persisited, so just find it from the db
            model.find(id)
          else
            # Looks like its not around! Better generate it from attributes
            record = model.new
            record.attributes.each do |attr, val|
              record.send("#{attr}=", attrs[attr])
            end
            record
          end
        else
          model.new
        end
      end
    end
  end
end