module Conglomerate::Serializer

Attributes

context[RW]
objects[RW]

Public Class Methods

included(descendant) click to toggle source
# File lib/conglomerate/serializer.rb, line 3
def self.included(descendant)
  descendant.extend(ClassMethods)
end
new(objects, options = {}) click to toggle source
# File lib/conglomerate/serializer.rb, line 7
def initialize(objects, options = {})
  self.objects = [*objects].compact
  self.context = options.fetch(:context, nil)
end

Public Instance Methods

serialize() click to toggle source
# File lib/conglomerate/serializer.rb, line 12
def serialize
  {
    "collection" => actions.inject({}) do |collection, action|
      send("apply_#{action}", collection)
    end
  }
end

Private Instance Methods

actions() click to toggle source
# File lib/conglomerate/serializer.rb, line 24
def actions
  [:version, :href, :queries, :commands, :items, :template, :links]
end
apply_commands(collection) click to toggle source
# File lib/conglomerate/serializer.rb, line 86
def apply_commands(collection)
  commands = self.class._commands.map do |command|
    build_command(
      command[:rel], command[:data], command[:prompt], command[:block]
    )
  end

  if commands.empty?
    collection
  else
    collection.merge({"commands" => commands})
  end
end
apply_data(collection, options = {}) click to toggle source
# File lib/conglomerate/serializer.rb, line 47
def apply_data(collection, options = {})
  data = options.fetch(:data, [])
  object = options.fetch(:object, nil)
  default_value = options.fetch(:default_value, nil)
  build_template = options.fetch(:build_template, false)

  data = data.map do |datum|
    name = datum[:name]
    type = datum.fetch(:type, :value)
    prompt = datum.fetch(:prompt, nil)
    value = sanitize_value(
      object, :name => name, :type => type, :default_value => default_value
    )
    value = format_value(value)

    {"name" => name.to_s, type.to_s => value}.tap do |d|
      d["prompt"] = prompt if build_template && prompt
    end
  end

  if data.empty?
    collection
  else
    collection.merge({"data" => data})
  end
end
apply_href(collection, options = {}) click to toggle source
# File lib/conglomerate/serializer.rb, line 32
def apply_href(collection, options = {})
  proc = options.fetch(:proc, self.class._href)
  object = options.fetch(:object, nil)

  if proc
    if object
      collection.merge({"href" => context.instance_exec(object, &proc)})
    else
      collection.merge({"href" => context.instance_eval(&proc)})
    end
  else
    collection
  end
end
apply_items(collection) click to toggle source
# File lib/conglomerate/serializer.rb, line 100
def apply_items(collection)
  items = objects.map do |object|
    item = {}

    if self.class._item_href
      item = apply_href(
        item, :proc => self.class._item_href, :object => object
      )
    end

    attributes = self.class._attributes
    item = apply_data(item, :data => attributes, :object => object)

    links = self.class._attributes
      .select { |attr| attr[:block] }
    links += self.class._item_links

    if links.empty?
      item.empty? ? nil : item
    else
      apply_links(item, :links => links, :object => object)
    end
  end

  if items.compact.empty?
    collection
  else
    collection.merge({"items" => items})
  end
end
apply_queries(collection) click to toggle source
# File lib/conglomerate/serializer.rb, line 74
def apply_queries(collection)
  queries = self.class._queries.map do |query|
    build_query(query[:rel], query[:data], query[:block])
  end

  if queries.empty?
    collection
  else
    collection.merge({"queries" => queries})
  end
end
apply_template(collection) click to toggle source
# File lib/conglomerate/serializer.rb, line 131
def apply_template(collection)
  attrs = self.class._attributes
    .select { |attr| attr[:template] }
  attrs += self.class._templates

  if attrs.empty?
    collection
  else
    collection.merge(
      {
        "template" => apply_data(
          {}, :data => attrs, :default_value => "", :build_template => true
        )
      }
    )
  end
end
apply_version(collection) click to toggle source
# File lib/conglomerate/serializer.rb, line 28
def apply_version(collection)
  collection.merge({"version" => "1.0"})
end
blank?(value) click to toggle source
# File lib/conglomerate/serializer.rb, line 237
def blank?(value)
  if value.is_a?(String)
    value !~ /[^[:space:]]/
  else
    value.respond_to?(:empty?) ? value.empty? : !value
  end
end
build_command(rel, data, prompt, block) click to toggle source
# File lib/conglomerate/serializer.rb, line 191
def build_command(rel, data, prompt, block)
  command = {"rel" => rel.to_s}
  command = apply_href(command, :proc => block)
  command["prompt"] = prompt if prompt
  apply_data(command, :data => data, :default_value => "")
end
build_query(rel, data, block) click to toggle source
# File lib/conglomerate/serializer.rb, line 185
def build_query(rel, data, block)
  query = {"rel" => rel.to_s}
  query = apply_href(query, :proc => block)
  apply_data(query, :data => data, :default_value => "")
end
format_value(value) click to toggle source
# File lib/conglomerate/serializer.rb, line 224
def format_value(value)
  case value
  when DateTime
    value.to_time.utc.iso8601.sub(/\+00:00$/, "Z")
  when Time
    value.utc.iso8601.sub(/\+00:00$/, "Z")
  when Date
    value.strftime("%Y-%m-%d")
  else
    value
  end
end
present?(value) click to toggle source
# File lib/conglomerate/serializer.rb, line 245
def present?(value)
  !blank?(value)
end
sanitize_value(object, options = {}) click to toggle source
# File lib/conglomerate/serializer.rb, line 206
def sanitize_value(object, options = {})
  name = options.fetch(:name)
  type = options.fetch(:type, :value)
  default_value = options.fetch(:default_value, nil)

  if object.nil? || object.send(name).nil?
    if type == :array
      []
    elsif type == :object
      {}
    else
      default_value
    end
  else
    object.send(name)
  end
end