module Spaceship::ConnectAPI::Models

Attributes

types[RW]
types_cache[RW]

Public Class Methods

find_class(model_data) click to toggle source
# File spaceship/lib/spaceship/connect_api/model.rb, line 97
def self.find_class(model_data)
  # Initialize cache
  @types_cache ||= {}

  # Find class in cache
  type_string = model_data["type"]
  type_class = @types_cache[type_string]
  return type_class if type_class

  # Find class in array
  type_class = @types.find do |type|
    type.type == type_string
  end

  # Cache and return class
  @types_cache[type_string] = type_class
  return type_class
end
inflate_model(model_data, included) click to toggle source
# File spaceship/lib/spaceship/connect_api/model.rb, line 116
def self.inflate_model(model_data, included)
  # Find class
  type_class = find_class(model_data)
  raise "No type class found for #{model_data['type']}" unless type_class

  # Get id and attributes needed for inflating
  id = model_data["id"]
  attributes = model_data["attributes"]

  # Instantiate object and inflate relationships
  relationships = model_data["relationships"] || []
  type_instance = type_class.new(id, attributes)
  type_instance = inflate_model_relationships(type_instance, relationships, included)

  return type_instance
end
inflate_model_relationships(type_instance, relationships, included) click to toggle source
# File spaceship/lib/spaceship/connect_api/model.rb, line 133
def self.inflate_model_relationships(type_instance, relationships, included)
  # Relationship attributes to set
  attributes = {}

  # 1. Iterate over relationships
  # 2. Find id and type
  # 3. Find matching id and type in included
  # 4. Inflate matching data and set in attributes
  relationships.each do |key, value|
    # Validate data exists
    value_data_or_datas = value["data"]
    next unless value_data_or_datas

    # Map an included data object
    map_data = lambda do |value_data|
      id = value_data["id"]
      type = value_data["type"]

      relationship_data = included.find do |included_data|
        id == included_data["id"] && type == included_data["type"]
      end

      inflate_model(relationship_data, included) if relationship_data
    end

    # Map a hash or an array of data
    if value_data_or_datas.kind_of?(Hash)
      attributes[key] = map_data.call(value_data_or_datas)
    elsif value_data_or_datas.kind_of?(Array)
      attributes[key] = value_data_or_datas.map(&map_data)
    end
  end

  type_instance.update_attributes(attributes)

  return type_instance
end
parse(json) click to toggle source
# File spaceship/lib/spaceship/connect_api/model.rb, line 80
def self.parse(json)
  data = json["data"]
  raise "No data" unless data

  included = json["included"] || []

  if data.kind_of?(Hash)
    inflate_model(data, included)
  elsif data.kind_of?(Array)
    return data.map do |model_data|
      inflate_model(model_data, included)
    end
  else
    raise "'data' is neither a hash nor an array"
  end
end