module DataMapper::Serialize

Constants

TAG_NAME
VERSION

Public Class Methods

included(descendant) click to toggle source

Include a callback to register the YAML output

@param [DataMapper::Model] descendant

@return [undefined]

@api private

# File lib/dm-serializer/to_yaml.rb, line 14
def self.included(descendant)
  YAML.add_domain_type(TAG_NAME, descendant.name) do |_tag, values|
    values
  end
end

Public Instance Methods

as_json(options = {}) click to toggle source

Converts the resource into a hash of properties.

@param [Hash] options

Additional options.

@return [Hash{String => String}]

The hash of resources properties.

@since 1.0.1

# File lib/dm-serializer/to_json.rb, line 18
def as_json(options = {})
  options = {} if options.nil?
  result  = {}

  properties_to_serialize(options).each do |property|
    property_name = property.name
    value = __send__(property_name)
    result[property_name] = value.kind_of?(DataMapper::Model) ? value.name : value
  end

  # add methods
  Array(options[:methods]).each do |method|
    next unless respond_to?(method)
    result[method] = __send__(method)
  end

  # Note: if you want to include a whole other model via relation, use
  # :methods:
  #
  #   comments.to_json(:relationships=>{:user=>{:include=>[:first_name],:methods=>[:age]}})
  #
  # TODO: This needs tests and also needs to be ported to #to_xml and
  # #to_yaml
  if options[:relationships]
    options[:relationships].each do |relationship_name, opts|
      if respond_to?(relationship_name)
        result[relationship_name] = __send__(relationship_name).to_json(opts.merge(:to_json => false))
      end
    end
  end

  result
end
encode_with(coder, options = {}) click to toggle source

A callback to encode the resource in the YAML stream

@param [#add] coder

handles adding the values to the output

@param [Hash] options

optional Hash configuring the output

@return [undefined]

@api public

# File lib/dm-serializer/to_yaml.rb, line 49
def encode_with(coder, options = {})
  coder.tag   = to_yaml_type  if coder.respond_to?(:tag=)
  coder.style = to_yaml_style if coder.respond_to?(:style=)

  methods = []

  methods.concat properties_to_serialize(options).map { |property| property.name }
  methods.concat Array(options[:methods])

  methods.each do |method|
    coder.add(method.to_s, __send__(method))
  end
end
properties_to_serialize(options) click to toggle source

Returns propreties to serialize based on :only or :exclude arrays, if provided :only takes precendence over :exclude

@return [Array]

Properties that need to be serialized.
# File lib/dm-serializer/common.rb, line 11
def properties_to_serialize(options)
  only_properties     = Array(options[:only])
  excluded_properties = Array(options[:exclude])

  model.properties(repository.name).reject do |p|
    if only_properties.include? p.name
      false
    else
      excluded_properties.include?(p.name) ||
      !(only_properties.empty? ||
      only_properties.include?(p.name))
    end
  end
end
to_csv(*args) click to toggle source

Serialize a Resource to comma-separated values (CSV).

@return <String> a CSV representation of the Resource

# File lib/dm-serializer/to_csv.rb, line 19
def to_csv(*args)
  options = args.first || {}
  options = options.to_h if options.respond_to?(:to_h)
  options[:writer] = '' unless options.has_key? :writer

  CSV.generate(options[:writer]) do |csv|
    row = properties_to_serialize(options).map do |property|
      __send__(property.name).to_s
    end
    csv << row
  end
end
to_json(*args) click to toggle source

Serialize a Resource to JavaScript Object Notation (JSON; RFC 4627)

@return <String> a JSON representation of the Resource

# File lib/dm-serializer/to_json.rb, line 55
def to_json(*args)
  options = args.first
  options = {} unless options.kind_of?(Hash)

  result = as_json(options)

  # default to making JSON
  if options.fetch(:to_json, true)
    MultiJson.encode(result)
  else
    result
  end
end
to_xml(opts = {}) click to toggle source

Serialize a Resource to XML.

@return [LibXML::Document, Nokogiri::Document, REXML::Document]

An XML representation of this Resource.
# File lib/dm-serializer/to_xml.rb, line 11
def to_xml(opts = {})
  xml = XML.serializer
  xml.output(to_xml_document(opts)).to_s
end
to_xml_document(opts={}, doc = nil) click to toggle source

This method requires certain methods to be implemented in the individual serializer library subclasses:

  • new_document

  • root_node

  • add_property_node

  • add_node

# File lib/dm-serializer/to_xml.rb, line 23
def to_xml_document(opts={}, doc = nil)
  xml = XML.serializer
  doc ||= xml.new_document

  default_xml_element_name = lambda {
    DataMapper::Inflector.underscore(model.name).tr("/", "-")
  }

  root = xml.root_node(
    doc,
    (opts[:element_name] || default_xml_element_name[])
  )

  properties_to_serialize(opts).each do |property|
    value = __send__(property.name)
    attrs = {}

    unless property.primitive == String
      attrs['type'] = property.primitive.to_s.downcase
    end

    xml.add_node(root, property.name.to_s, value, attrs)
  end

  Array(opts[:methods]).each do |meth|
    if self.respond_to?(meth)
      xml_name = meth.to_s.gsub(/[^a-z0-9_]/, '')
      value = __send__(meth)

      unless value.nil?
        if value.respond_to?(:to_xml_document)
          xml.add_xml(root, value.to_xml_document)
        else
          xml.add_node(root, xml_name, value.to_s)
        end
      end
    end
  end

  doc
end
to_yaml(options = {}) click to toggle source

Serialize a Resource to YAML

@example

yaml = resource.to_yaml  # => a valid YAML string

@param [Hash] options

@return [String]

@api public

# File lib/dm-serializer/to_yaml.rb, line 30
def to_yaml(options = {})
  YAML.quick_emit(object_id, options) do |out|
    out.map(to_yaml_type, to_yaml_style) do |map|
      encode_with(map, options.kind_of?(Hash) ? options : {})
    end
  end
end

Private Instance Methods

to_yaml_style() click to toggle source

Return the YAML style to use for the output

@return [Integer]

@api private

# File lib/dm-serializer/to_yaml.rb, line 79
def to_yaml_style
  Psych::Nodes::Mapping::ANY
end
to_yaml_type() click to toggle source

Return the YAML type to use for the output

@return [String]

@api private

# File lib/dm-serializer/to_yaml.rb, line 70
def to_yaml_type
  "!#{TAG_NAME}:#{model.name}"
end