Module: DataMapper::Serializer

Defined in:
lib/dm-serializer/xml.rb,
lib/dm-serializer/common.rb,
lib/dm-serializer/to_csv.rb,
lib/dm-serializer/to_xml.rb,
lib/dm-serializer/to_json.rb,
lib/dm-serializer/to_yaml.rb,
lib/dm-serializer/xml/rexml.rb,
lib/dm-serializer/xml/libxml.rb,
lib/dm-serializer/xml/nokogiri.rb

Defined Under Namespace

Modules: Collection, ValidationErrors, XML

Constant Summary collapse

TAG_NAME =
"ruby/DataMapper,#{DataMapper::VERSION}".freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(descendant) ⇒ undefined

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Include a callback to register the YAML output

Parameters:

  • descendant (DataMapper::Model)

Returns:

  • (undefined)


14
15
16
17
18
# 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

Instance Method Details

#as_json(options = {}) ⇒ Hash{String => String}

Converts the resource into a hash of properties.

Parameters:

  • options (Hash) (defaults to: {})

    Additional options.

Returns:

  • (Hash{String => String})

    The hash of resources properties.

Since:

  • 1.0.1



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# 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 = {}) ⇒ undefined

A callback to encode the resource in the YAML stream

Parameters:

  • coder (#add)

    handles adding the values to the output

  • options (Hash) (defaults to: {})

    optional Hash configuring the output

Returns:

  • (undefined)


49
50
51
52
53
54
55
56
57
58
59
60
61
# 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) ⇒ Array

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

Returns:

  • (Array)

    Properties that need to be serialized.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 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) ⇒ String

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

Returns:

  • (String)

    a CSV representation of the Resource



19
20
21
22
23
24
25
26
27
28
29
30
# 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) ⇒ String

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

Returns:

  • (String)

    a JSON representation of the Resource



55
56
57
58
59
60
61
62
63
64
65
66
67
# 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 = {}) ⇒ LibXML::Document, ...

Serialize a Resource to XML.

Returns:

  • (LibXML::Document, Nokogiri::Document, REXML::Document)

    An XML representation of this Resource.



11
12
13
14
# 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) ⇒ Object

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

  • new_document

  • root_node

  • add_property_node

  • add_node



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# 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 = {}) ⇒ String

Serialize a Resource to YAML

Examples:

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

Parameters:

  • options (Hash) (defaults to: {})

Returns:

  • (String)


30
31
32
33
34
35
36
# 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

#to_yaml_styleInteger

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return the YAML style to use for the output

Returns:

  • (Integer)


79
80
81
# File 'lib/dm-serializer/to_yaml.rb', line 79

def to_yaml_style
  Psych::Nodes::Mapping::ANY
end