class Hat::Sideloading::JsonDeserializer

Attributes

identity_map[RW]
json[RW]
key_to_class_mappings[RW]
root_key[RW]
sideload_map[RW]

Public Class Methods

new(json) click to toggle source
# File lib/hat/sideloading/json_deserializer.rb, line 14
def initialize(json)
  @json = json
  @root_key = json['meta']['root_key'].to_s
  @identity_map = IdentityMap.new
  @sideload_map = SideloadMap.new(json, root_key)
  @key_to_class_mappings = {}
end

Public Instance Methods

deserialize() click to toggle source
# File lib/hat/sideloading/json_deserializer.rb, line 22
def deserialize
  json[root_key].map do |json_item|
    create_from_json_item(target_class_for_key(root_key), json_item)
  end
end

Private Instance Methods

apply_linked_relations_to_target(target, links) click to toggle source
# File lib/hat/sideloading/json_deserializer.rb, line 53
def apply_linked_relations_to_target(target, links)

  target_class_name = target.class.name

  links.each do |relation_name, value|
    if value.kind_of?(Array)
      target.send("#{relation_name}=", create_has_manys(target_class_name, relation_name, value))
      target.send("#{relation_name.singularize}_ids=", value)
    else
      target.send("#{relation_name}=", create_belongs_to(target_class_name, relation_name, value))
      target.send("#{relation_name}_id=", value)
    end
  end
end
create_belongs_to(parent_class_name, sideload_key, id) click to toggle source
# File lib/hat/sideloading/json_deserializer.rb, line 68
def create_belongs_to(parent_class_name, sideload_key, id)

  sideload_key = mapped_sideload_key_for(parent_class_name, sideload_key)

  if sideloaded_json = sideload_map.get(sideload_key, id)
    sideloaded_object = create_from_json_item(target_class_for_key(sideload_key), sideloaded_json)
  else
    nil
  end
end
create_from_json_item(target_class, json_item) click to toggle source
# File lib/hat/sideloading/json_deserializer.rb, line 32
def create_from_json_item(target_class, json_item)

  return nil unless target_class

  existing_deserialized = identity_map.get(target_class.name, json_item['id'])
  return existing_deserialized if existing_deserialized

  relations = {}
  target_class_name = target_class.name

  #we have to add this before we process subtree or we'll get circular issues
  target = target_class.new(json_item.with_indifferent_access)
  identity_map.put(target_class_name, json_item['id'], target)

  links = json_item['links'] || {}
  apply_linked_relations_to_target(target, links)

  target

end
create_has_manys(parent_class_name, sideload_key, ids) click to toggle source
# File lib/hat/sideloading/json_deserializer.rb, line 79
def create_has_manys(parent_class_name, sideload_key, ids)
  sideload_key = mapped_sideload_key_for(parent_class_name, sideload_key)
  target_class = target_class_for_key(sideload_key)
  sideloaded_json_items = sideload_map.get_all(sideload_key, ids)

  sideloaded_json_items.map do |json_item|
    create_from_json_item(target_class, json_item)
  end
end
mapped_sideload_key_for(parent_class_name, sideload_key) click to toggle source
# File lib/hat/sideloading/json_deserializer.rb, line 89
def mapped_sideload_key_for(parent_class_name, sideload_key)

  resolve_class_mappings_for(parent_class_name)
  class_mapping = key_to_class_mappings[parent_class_name]

  if attribute_mapping = class_mapping[sideload_key.to_sym]
    return attribute_mapping.name.underscore
  end

  sideload_key
end
resolve_class_mappings_for(parent_class_name) click to toggle source
# File lib/hat/sideloading/json_deserializer.rb, line 101
def resolve_class_mappings_for(parent_class_name)
  unless key_to_class_mappings[parent_class_name]
    mapping_class_name = "#{parent_class_name}DeserializerMapping"
    if Object.const_defined?(mapping_class_name)
      key_to_class_mappings[parent_class_name] = mapping_class_name.constantize.mappings
    else
      key_to_class_mappings[parent_class_name] = {}
    end
  end
end
target_class_for_key(key) click to toggle source
# File lib/hat/sideloading/json_deserializer.rb, line 112
def target_class_for_key(key)
  key.to_s.singularize.camelize.constantize
rescue NameError
  nil
end