module SnFoil::JsonapiDeserializer

Attributes

included[R]
object[R]
options[R]

Public Class Methods

new(object, included: nil, **options) click to toggle source
# File lib/sn_foil/jsonapi_deserializer.rb, line 36
def initialize(object, included: nil, **options)
  @object = object
  @included = included || object[:included]
  @options = options
end

Public Instance Methods

attribute(key, **options) click to toggle source
# File lib/sn_foil/jsonapi_deserializer.rb, line 17
def attribute(key, **options)
  @i_attribute_transforms ||= {}
  @i_attribute_transforms[key] = options.merge(transform_type: :attribute)
end
attribute_fields() click to toggle source
# File lib/sn_foil/jsonapi_deserializer.rb, line 42
def attribute_fields
  self.class.i_attribute_fields || []
end
attribute_transforms() click to toggle source
# File lib/sn_foil/jsonapi_deserializer.rb, line 46
def attribute_transforms
  self.class.i_attribute_transforms || {}
end
attributes(*fields) click to toggle source
# File lib/sn_foil/jsonapi_deserializer.rb, line 12
def attributes(*fields)
  @i_attribute_fields ||= []
  @i_attribute_fields |= fields
end
has_many(key, deserializer:, **options) click to toggle source
# File lib/sn_foil/jsonapi_deserializer.rb, line 28
def has_many(key, deserializer:, **options) # rubocop:disable Naming/PredicateName
  @i_attribute_transforms ||= {}
  @i_attribute_transforms[key] = options.merge(deserializer: deserializer, transform_type: :has_many)
end
has_one(key, deserializer:, **options) click to toggle source
# File lib/sn_foil/jsonapi_deserializer.rb, line 22
def has_one(key, deserializer:, **options) # rubocop:disable Naming/PredicateName
  @i_attribute_transforms ||= {}
  @i_attribute_transforms[key] = options.merge(deserializer: deserializer, transform_type: :has_one)
end
parse() click to toggle source
# File lib/sn_foil/jsonapi_deserializer.rb, line 54
def parse
  parse_data
end
Also aliased as: to_h
to_h()
Alias for: parse

Private Instance Methods

apply_attribute_transform(attributes, data, key, transform_type:, **opts) click to toggle source
# File lib/sn_foil/jsonapi_deserializer.rb, line 91
def apply_attribute_transform(attributes, data, key, transform_type:, **opts)
  case transform_type
  when :attribute
    parse_attribute_transform(attributes, data, key, **opts)
  when :has_one
    parse_has_one_relationship(attributes, data, key, **opts)
  when :has_many
    parse_has_many_relationship(attributes, data, key, **opts)
  end
end
build_attributes(data) click to toggle source
# File lib/sn_foil/jsonapi_deserializer.rb, line 69
def build_attributes(data)
  attributes = data_id({}, data)
  attributes = parse_standard_attributes(attributes, data) if data[:attributes]
  attribute_transforms.each do |key, opts|
    attributes = apply_attribute_transform(attributes, data, key, **opts)
  end
  attributes
end
check_for_id(id, lid) click to toggle source
# File lib/sn_foil/jsonapi_deserializer.rb, line 155
def check_for_id(id, lid)
  raise ::ArgumentError, "missing keyword: id or lid for type: #{type}" unless id || lid
end
data_id(attributes, data) click to toggle source
# File lib/sn_foil/jsonapi_deserializer.rb, line 78
def data_id(attributes, data)
  if data[:id]
    attributes[:id] = data[:id]
  elsif data[:'local:id']
    attributes[:lid] = data[:'local:id']
  end
  attributes
end
lookup_relationship(type:, id: nil, lid: nil, **_opts) click to toggle source
# File lib/sn_foil/jsonapi_deserializer.rb, line 142
def lookup_relationship(type:, id: nil, lid: nil, **_opts)
  check_for_id(id, lid)

  included&.find do |x|
    x[:type].eql?(type) &&
      if id
        x[:id].eql?(id)
      elsif lid
        x[:'local:id'].eql?(lid)
      end
  end
end
parse_attribute_transform(attributes, data, key, **opts) click to toggle source
# File lib/sn_foil/jsonapi_deserializer.rb, line 102
def parse_attribute_transform(attributes, data, key, **opts)
  return attributes unless data.dig(:attributes, key)

  attributes.merge({ opts.fetch(:key) { key } => data[:attributes][key] })
end
parse_data() click to toggle source
# File lib/sn_foil/jsonapi_deserializer.rb, line 61
def parse_data
  if object[:data].is_a? Array
    object[:data].map { |d| build_attributes(d) }
  else
    build_attributes(object[:data])
  end
end
parse_has_many_relationship(attributes, data, key, deserializer:, **opts) click to toggle source
# File lib/sn_foil/jsonapi_deserializer.rb, line 129
def parse_has_many_relationship(attributes, data, key, deserializer:, **opts)
  array_data = data.dig(:relationships, key, :data)
  return attributes unless array_data

  attributes[opts.fetch(:key) { key }] = array_data.map do |resource_data|
    resource_data = data_id(resource_data, resource_data)
    attribute_data = lookup_relationship(resource_data)
    relationship_data = { data: attribute_data || resource_data }
    deserializer.new(relationship_data, **options, included: included).parse
  end
  attributes
end
parse_has_one_relationship(attributes, data, key, deserializer:, **opts) click to toggle source
# File lib/sn_foil/jsonapi_deserializer.rb, line 118
def parse_has_one_relationship(attributes, data, key, deserializer:, **opts)
  resource_data = data.dig(:relationships, key, :data)
  return attributes unless resource_data

  resource_data = data_id(resource_data, resource_data)
  attribute_data = lookup_relationship(resource_data)
  relationship_data = { data: attribute_data || resource_data }
  attributes[opts.fetch(:key) { key }] = deserializer.new(relationship_data, **options, included: included).parse
  attributes
end
parse_relationships(attributes, data) click to toggle source
# File lib/sn_foil/jsonapi_deserializer.rb, line 108
def parse_relationships(attributes, data)
  self.class.has_one_relationships.each do |key, opts|
    attributes = has_one_relationship(attributes, data, key, **opts)
  end
  self.class.has_many_relationships.each do |key, opts|
    attributes = has_many_relationship(attributes, data, key, **opts)
  end
  attributes
end
parse_standard_attributes(attributes, data) click to toggle source
# File lib/sn_foil/jsonapi_deserializer.rb, line 87
def parse_standard_attributes(attributes, data)
  attributes.merge!(data[:attributes].select { |k, _| attribute_fields.include? k })
end