lib/serialize_with_options.rb
require 'serialize_with_options/railtie' if defined?(Rails)
module SerializeWithOptions
def self.extended(base)
base.class_attribute :serialization_conf
base.class_attribute :serialization_opts
end
def serialize_with_options(set = :default, &block)
conf = self.serialization_conf || {}
opts = self.serialization_opts || {}
conf[set] = Config.new.instance_eval(&block)
self.serialization_conf = conf
self.serialization_opts = opts
include InstanceMethods
end
def serialization_configuration(set)
conf = self.serialization_conf
conf &&= conf[set] || conf[:default]
conf.try(:dup) || { :methods => nil, :only => nil, :except => nil }
end
def serialization_options(set)
options = self.serialization_opts
options[set] ||= serialization_configuration(set).tap do |opts|
includes = opts.delete(:includes)
if includes
opts[:include] = includes.inject({}) do |hash, class_name|
if class_name.is_a? Hash
hash.merge(class_name)
else
begin
klass = class_name.to_s.classify.constantize
hash[class_name] = klass.serialization_configuration(set)
hash[class_name][:include] = nil if hash[class_name].delete(:includes)
hash
rescue NameError
hash.merge(class_name => { :include => nil })
end
end
end
end
end
self.serialization_opts = options
options[set]
end
class Config
undef_method :methods
Instructions = [:skip_instruct, :dasherize, :skip_types, :root_in_json].freeze
def initialize
@data = { :methods => nil, :only => nil, :except => nil }
end
def method_missing(method, *args)
@data[method] = Instructions.include?(method) ? args.first : args
@data
end
end
module InstanceMethods
%w(to_xml to_json as_json).each do |method_name|
define_method method_name do |*args|
set, opts = parse_serialization_options(args)
super self.class.serialization_options(set).deep_merge(opts)
end
end
private
def parse_serialization_options(args)
opts = args.extract_options!
set = args.shift || :default
[set, opts]
end
end
end