class Serializer::Serializable
Some utility methods to faciliate serialization of data fields to Hash, JSON, or YAML shared by all subclasses. This class assumes that HappyMapper is used for declaration of fields to be serialized.
Data Model¶ ↑
-
{Serializable} = utility methods to faciliate serialization to Hash, JSON, or YAML
-
{Manifest} = adds methods for marshalling/unmarshalling data to a persistent XML file format
-
@see github.com/jnunemaker/happymapper @note Copyright © 2012 by The Board of Trustees of the Leland Stanford
Junior University.
All rights reserved. See {file:LICENSE.rdoc} for details.
Public Class Methods
Source
# File lib/serializer/serializable.rb, line 142 def self.deep_diff(*hashes) diff = {} case hashes.length when 4 ltag, left, rtag, right = hashes when 2 ltag = :left left = hashes[0] rtag = :right right = hashes[1] else raise ArgumentError, "wrong number of arguments (#{hashes.length} for 2 or 4)" end (left.keys | right.keys).each do |k| if left[k] != right[k] diff[k] = if left[k].is_a?(Hash) && right[k].is_a?(Hash) deep_diff(ltag, left[k], rtag, right[k]) else { ltag => left[k], rtag => right[k] } end end end diff end
@api internal @param hashes [Array<Hash>] The hashes to be compared, with optional name tags @return [Hash] Generate a hash containing the differences between two hashes
(recursively descend parallel trees of hashes)
Source
# File lib/serializer/serializable.rb, line 22 def initialize(opts = {}) opts.each do |key, value| errmsg = "#{key} is not a variable name in #{self.class.name}" raise(Moab::MoabRuntimeError, errmsg) unless variable_names.include?(key.to_s) || key == :test instance_variable_set("@#{key}", value) end end
A flexible initializer based on the DataMapper “create factory” design pattern. @see datamapper.org/docs/create_and_destroy.html @see Serializable#initialize @param opts [Hash<Symbol,Object>] a hash containing any number of symbol => value pairs.
The symbols should correspond to attributes declared using HappyMapper syntax
Public Instance Methods
Source
# File lib/serializer/serializable.rb, line 83 def array_to_hash(array, summary = false) item_hash = {} array.each_index do |index| item = array[index] ikey = item.respond_to?(:key) && item.key ? item.key : index item_hash[ikey] = item.respond_to?(:to_hash) ? item.to_hash(summary) : item end item_hash end
@api internal @param array [Array] The array to be converted to a hash @return [Hash] Generate a hash from an array of objects.
If the array member has a field tagged as a key, that field will be used as the hash.key. Otherwise the index position of the array member will be used as the key
Source
# File lib/serializer/serializable.rb, line 122 def diff(other) raise(Moab::MoabRuntimeError, 'Cannot compare different classes') if self.class != other.class left = other.to_hash right = to_hash if key.nil? || other.key.nil? ltag = :old rtag = :new else ltag = other.key rtag = key end Serializable.deep_diff(ltag, left, rtag, right) end
@api internal @param other [Serializable] The other object being compared @return [Hash] Generate a hash containing the differences between two objects of the same type
Source
# File lib/serializer/serializable.rb, line 72 def key return send(key_name) if key_name nil end
@api internal @return [String] For the current object instance, return the string to use as a hash key
Source
# File lib/serializer/serializable.rb, line 57 def key_name unless defined?(@key_name) @key_name = nil self.class.attributes.each do |attribute| if attribute.options[:key] @key_name = attribute.name break end end end @key_name end
@api internal @return [String] Determine which attribute was marked as an object instance key.
Keys are indicated by option :key=true when declaring the object's variables. This follows the same convention as used by DataMapper
Source
# File lib/serializer/serializable.rb, line 115 def summary to_hash(true) end
@return [Hash] Calls to_hash
(summary=true)
Source
# File lib/serializer/serializable.rb, line 96 def to_hash(summary = false) oh = {} vars = summary ? variables.select { |v| summary_fields.include?(v.name) } : variables vars.each do |variable| key = variable.name.to_s value = send(variable.name) oh[key] = case value when Array array_to_hash(value, summary) when Serializable value.to_hash else value end end oh end
@api internal @return [Hash] Recursively generate an Hash containing the object’s properties @param summary [Boolean] Controls the depth and detail of recursion
Source
# File lib/serializer/serializable.rb, line 169 def to_json(summary = false) hash = to_hash(summary) JSON.pretty_generate(hash) end
@api internal @return [String] Generate JSON output from a hash of the object’s variables
Source
# File lib/serializer/serializable.rb, line 176 def to_yaml(summary = false) to_hash(summary).to_yaml end
@api internal @return [String] Generate YAML output from a hash of the object’s variables
Source
# File lib/serializer/serializable.rb, line 48 def variable_names variables.collect(&:name) end
@api internal @return [Array] Extract the names of the variables
Source
# File lib/serializer/serializable.rb, line 33 def variables attributes = self.class.attributes elements = self.class.elements attributes + elements # text_node enhancement added by unhappymapper, which is not being used # It enables elements having both attributes and a text value #text_node = [] #if self.class.instance_variable_defined?("@text_node") # text_node << self.class.instance_variable_get("@text_node") #end #attributes + elements + text_node end
@api internal @return [Array] A list of HappyMapper xml attribute, element and text nodes declared for the class