class MotionJsonApi::Resource

Attributes

attributes[RW]
id[RW]
included[RW]
meta[RW]
relationships[RW]
top_level[RW]

Public Class Methods

_resource_type() click to toggle source
# File lib/motion-json-api/resource.rb, line 42
def self._resource_type
  @_resource_type
end
attribute(attribute, options = {}) click to toggle source
# File lib/motion-json-api/resource.rb, line 46
def self.attribute(attribute, options = {})
  key = options.fetch(:key, attribute)
  define_method(key) do
    self.attributes.fetch(attribute.to_s, nil)
  end
end
has_many(relation, options = {}) click to toggle source
# File lib/motion-json-api/resource.rb, line 72
def self.has_many(relation, options = {})
  key = options.fetch(:key, relation)
  define_method(key) do
    relationship = self.relationships.fetch(relation.to_s, {})

    relationship.fetch("data", []).map do |data|
      object = _find_in_included(data["id"], data["type"])

      if object
        Resource._object_handler({"data" => object}, self.top_level, self.included)
      else
        Resource._object_handler({"data" => data}, self.top_level, self.included)
      end
    end
  end
end
has_one(relation, options = {}) click to toggle source
# File lib/motion-json-api/resource.rb, line 53
def self.has_one(relation, options = {})
  key = options.fetch(:key, relation)
  define_method(key) do
    relationship = self.relationships.fetch(relation.to_s, {})
    data = relationship.fetch("data", nil)
    if data && !data.empty?
      object = _find_in_included(data["id"], data["type"])
      if object
        payload = {"data" => object, "links" => relationship.fetch("links", {})}
        Resource._object_handler(payload, self.top_level, self.included)
      else
        {"id" => data["id"], "type" => data["type"]}
      end
    else
      nil
    end
  end
end
new(object, top_level = [], included = []) click to toggle source
# File lib/motion-json-api/resource.rb, line 17
def initialize(object, top_level = [], included = [])
  @id = object["data"]["id"]
  @attributes = object["data"].fetch("attributes", {})
  @relationships = object["data"].fetch("relationships", {})
  @meta = object.fetch("meta") do
    object["data"].fetch("meta", {})
  end
  @links = object.fetch("links") do
    object["data"].fetch("links", {})
  end
  @top_level = top_level
  @included = included
end
resource_type(resource_type) click to toggle source
# File lib/motion-json-api/resource.rb, line 38
def self.resource_type(resource_type)
  @_resource_type = resource_type
end

Private Class Methods

_descendants() click to toggle source
# File lib/motion-json-api/resource.rb, line 111
def self._descendants
  Resource.descendants
end
_klass_for_type(type) click to toggle source
# File lib/motion-json-api/resource.rb, line 99
def self._klass_for_type(type)
  resource_klass = Resource._descendants.select do |klass|
    type == klass._resource_type.to_s
  end.first

  unless resource_klass
    raise UndefinedResource, "Couldn’t find defined resource for type: #{type}"
  end

  resource_klass
end
_object_handler(object, top_level, included = nil) click to toggle source
# File lib/motion-json-api/resource.rb, line 115
def self._object_handler(object, top_level, included = nil)
  included ||= self.included || object.fetch("included", [])
  top_level ||= self.top_level || object["data"]
  top_level = [top_level].flatten
  case object["data"]
  when Array
    return Resources.new(object, top_level, included)
  when Hash
    resource_klass = Resource._klass_for_type(object["data"]["type"])
    resource_klass.new(object, top_level, included)
  end
end

Public Instance Methods

set_meta(key, value) click to toggle source
# File lib/motion-json-api/resource.rb, line 31
def set_meta(key, value)
  if @meta.key?(key)
    @meta[key] = value
  end
end

Private Instance Methods

_find_in_included(id, type) click to toggle source
# File lib/motion-json-api/resource.rb, line 91
def _find_in_included(id, type)
  object = self.included.find { |x| x["id"] == id && x["type"] == type }
  if object.nil?
    object = self.top_level.find { |x| x["id"] == id && x["type"] == type }
  end
  object
end