Class: Strum::JsonDeserializer

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

Methods included from Service

#errors, #execute, #failure, #hook, included, #initialize, #method_missing, #on, #respond_to_missing?, #success, #valid?

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Strum::Service

Instance Method Details

#auditObject



14
15
16
# File 'lib/strum/json_deserializer.rb', line 14

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

#callObject



10
11
12
# File 'lib/strum/json_deserializer.rb', line 10

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

#deep_transform_keys(object) ⇒ Object



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

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



104
105
106
107
108
109
110
111
112
113
# File 'lib/strum/json_deserializer.rb', line 104

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



93
94
95
# File 'lib/strum/json_deserializer.rb', line 93

def includes(hash)
  hash[:included]
end

#inflectorObject



126
127
128
# File 'lib/strum/json_deserializer.rb', line 126

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

#merge_relations(hash) ⇒ Object



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

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



69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/strum/json_deserializer.rb', line 69

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



97
98
99
100
101
102
# File 'lib/strum/json_deserializer.rb', line 97

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



115
116
117
118
119
120
121
122
123
124
# File 'lib/strum/json_deserializer.rb', line 115

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



82
83
84
85
86
87
88
89
90
91
# File 'lib/strum/json_deserializer.rb', line 82

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



18
19
20
# File 'lib/strum/json_deserializer.rb', line 18

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

#root_errorsObject



22
23
24
# File 'lib/strum/json_deserializer.rb', line 22

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