Skip to content

Instantly share code, notes, and snippets.

@blt04
Created December 16, 2010 18:52
Show Gist options
  • Save blt04/743790 to your computer and use it in GitHub Desktop.
Save blt04/743790 to your computer and use it in GitHub Desktop.
Mongoid::Document XML and JSON serialization customizations
#
# This core extension customizes XML and JSON serialization in Mongoid::Document
# objects:
# * Serializes BSON::ObjectIDs as strings in XML
# * Removes leading underscores from attributes (such as _id, _type)
# * Allows documents to customize serialization even further by declaring a
# `serialize_attributes!` method, e.g.:
# def serialize_attributes!(attribute_hash)
# attribute_hash.delete(:unnecessary_key)
# attribute_hash[:password] = ''
# end
#
# It also adds support for serialization to Mongoid::Criteria objects. This is
# especially helpful when used with `respond_with`:
#
# def index
# @categories = Category.asc(:name)
# respond_with(@categories)
# end
#
module Mongoid
module Components
def self.included(base)
base.class_eval do
include Mongoid::Serialization::JSON
include Mongoid::Serialization::Xml
end
end
end
end
module Mongoid
module Serialization
# Returns a new hash with leading underscores removed from key names
def Serialization.clean_hash_keys(h)
h.inject({}) do |h, (k,v)|
# TODO: This converts symbols to strings unnecessarily
h[k.to_s =~ /^_/ ? k.to_s.gsub(/^_+/, '') : k] = v
h
end
end
module JSON
def as_json(*options)
Serialization.clean_hash_keys(super).tap do |h|
self.serialize_attributes!(h) if self.respond_to?(:serialize_attributes!)
end
end
end
module Xml
def to_xml(options = {}, &block)
XmlSerializer.new(self, options).serialize(&block)
end
class XmlSerializer < ActiveModel::Serializers::Xml::Serializer
def attributes_hash
Serialization.clean_hash_keys(super).tap do |h|
@serializable.serialize_attributes!(h) if @serializable.respond_to?(:serialize_attributes!)
end
end
end
end
end
end
class Mongoid::Criteria
def as_json(options = nil)
map { |v| v.as_json(options) }
end
def to_xml(options = {}, &block)
options = options.dup
options[:root] ||= ActiveSupport::Inflector.pluralize(ActiveSupport::Inflector.underscore(klass)).tr('/', '_')
entries.to_xml(options, &block)
end
end
class BSON::ObjectId
def to_xml(options)
# Serialize Mongo object IDs as a string
# (default uses a YAML representation)
key = ActiveSupport::XmlMini::rename_key(options[:root], options)
options[:builder].tag!(key, to_s)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment