Class: Strum::Json::Deserializer

Inherits:
Object
  • Object
show all
Includes:
Service
Defined in:
lib/strum/json/deserializer.rb

Overview

Deserialize JSON-API to hash(s)

Instance Method Summary collapse

Instance Method Details

#auditObject



16
17
18
# File 'lib/strum/json/deserializer.rb', line 16

def audit
  add_error(:root, :data_and_errors_must_not_coexist) unless !root_data[:data] ^ !root_errors[:errors]
end

#callObject



12
13
14
# File 'lib/strum/json/deserializer.rb', line 12

def call
  output(root_data[:data] ? prepare_output : root_errors[:errors])
end

#deep_transform_keys(object) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/strum/json/deserializer.rb', line 28

def deep_transform_keys(object)
  keys_to_sym = lambda do |object|
    case object
    when Hash
      object.keys.each do |key|
        value = object.delete(key)
        object[(key.respond_to?(:to_sym) ? inflector.underscore(key).to_sym : key)] = keys_to_sym[value]
      end
      object
    when Array
      object.map! { |e| keys_to_sym[e] }
    else
      object
    end
  end
  merge_relationships = lambda do |object|
    handle_attributes(object)
  end
  result = keys_to_sym >> merge_relationships
  result[object]
end

#handle_attributes(object) ⇒ Object



106
107
108
109
110
111
112
113
114
115
# File 'lib/strum/json/deserializer.rb', line 106

def handle_attributes(object)
  case object
  when Array
    object.map { |i| merge_relations(i) }
  when Hash
    merge_relations(object)
  else
    object
  end
end

#includes(hash) ⇒ Object



95
96
97
# File 'lib/strum/json/deserializer.rb', line 95

def includes(hash)
  hash[:included]
end

#inflectorObject



128
129
130
# File 'lib/strum/json/deserializer.rb', line 128

def inflector
  @inflector = Dry::Inflector.new
end

#merge_relations(hash) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/strum/json/deserializer.rb', line 50

def merge_relations(hash)
  if hash[:data].is_a?(Array)
    parse_array_relationships(hash)
  else
    relationships = relations(hash)
    included = includes(hash)
    prepare_relationships = lambda { |hash|
      hash.each do |key, value|
        if value.is_a?(Hash)
          hash[key.to_sym] = (value.values_at(:attributes)&.first || value.values_at(:data)&.first || value)
        end
      end
    }
    if relationships && hash[:data][:attributes]
      hash[:data][:attributes].merge!(prepare_relationships[relationships])
    end
    hash[:data][:attributes].merge!(prepare_includes(included)) if included && hash[:data][:attributes]
  end
  hash
end

#parse_array_relationships(hash) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/strum/json/deserializer.rb', line 71

def parse_array_relationships(hash)
  prepare_nested = lambda { |hash|
    hash.each do |key, value|
      hash[key.to_sym] = value.values_at(:data)&.first if value.is_a?(Hash)
    end
  }
  hash[:data].each do |element|
    relationships, included = element.values_at(:relationships, :included)
    element[:attributes].merge!(prepare_nested[relationships]) if relationships
    element[:attributes].merge!(prepare_nested[included]) if included
  end
end

#prepare_includes(includes) ⇒ Object



99
100
101
102
103
104
# File 'lib/strum/json/deserializer.rb', line 99

def prepare_includes(includes)
  includes.each_with_object({}) do |h, e|
    e[h[:type].to_sym] ||= []
    e[h[:type].to_sym] << h[:attributes]
  end
end

#prepare_outputObject



117
118
119
120
121
122
123
124
125
126
# File 'lib/strum/json/deserializer.rb', line 117

def prepare_output
  case root_data
  when Array
    root_data.map { |i| i[:data][:attributes] }
  when Hash
    root_data[:data].is_a?(Array) ? root_data[:data].map { |i| i[:attributes] } : root_data[:data][:attributes]
  else
    root_data
  end
end

#relations(hash) ⇒ Object



84
85
86
87
88
89
90
91
92
93
# File 'lib/strum/json/deserializer.rb', line 84

def relations(hash)
  case hash[:data]
  when Array
    hash[:data].map { |i| i[:relationships] }
  when Hash
    hash[:data][:relationships]
  else
    hash[:data]
  end
end

#root_dataObject



20
21
22
# File 'lib/strum/json/deserializer.rb', line 20

def root_data
  @root_data ||= deep_transform_keys(input)
end

#root_errorsObject



24
25
26
# File 'lib/strum/json/deserializer.rb', line 24

def root_errors
  @root_errors ||= deep_transform_keys(input)
end