Class: RubyJsonApiClient::AmsSerializer

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_json_api_client/serializers/ams_serializer.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ AmsSerializer

Returns a new instance of AmsSerializer.



9
10
11
12
13
14
15
16
17
# File 'lib/ruby_json_api_client/serializers/ams_serializer.rb', line 9

def initialize(options = {})
  if options[:json_parsing_method].nil?
    options[:json_parsing_method] = JSON.method(:parse)
  end

  options.each do |(field, value)|
    send("#{field}=", value)
  end
end

Instance Attribute Details

#json_parsing_methodObject

Returns the value of attribute json_parsing_method.



7
8
9
# File 'lib/ruby_json_api_client/serializers/ams_serializer.rb', line 7

def json_parsing_method
  @json_parsing_method
end

#storeObject

Returns the value of attribute store.



6
7
8
# File 'lib/ruby_json_api_client/serializers/ams_serializer.rb', line 6

def store
  @store
end

Instance Method Details

#_create_model(klass, data) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/ruby_json_api_client/serializers/ams_serializer.rb', line 68

def _create_model(klass, data)
  model = klass.new(meta: {})

  model.meta[:data] = data

  if data['links']
    model.meta[:links] = data['links']
  end

  data.reduce(model) do |record, (field, value)|
    if klass.has_field?(field.to_sym)
      record.send("#{field}=", value)
    end

    record
  end
end

#assert(test, failure_message) ⇒ Object



64
65
66
# File 'lib/ruby_json_api_client/serializers/ams_serializer.rb', line 64

def assert(test, failure_message)
  raise failure_message if !test
end

#extract_many(klass, response, key = nil) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/ruby_json_api_client/serializers/ams_serializer.rb', line 107

def extract_many(klass, response, key = nil)
  key = klass.to_s.underscore if key.nil?
  plural = ActiveSupport::Inflector.pluralize(key)

  data = transform(response)

  assert data[plural],
    "No key #{plural} in json response."

  assert data[plural].is_a?(Array),
    "Key #{plural} should be an array"

  data[plural].reduce([]) do |collection, json|
    collection << _create_model(klass, json)
  end
end

#extract_many_relationship(parent, name, options, response) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/ruby_json_api_client/serializers/ams_serializer.rb', line 124

def extract_many_relationship(parent, name, options, response)
  # given response this will find the relationship
  # for ams based apis the relationship will either be
  # 1) in links
  # 2) in sideloaded data
  data = transform(response)
  singular = ActiveSupport::Inflector.singularize(name)
  meta = parent.meta || {}
  meta_links = meta[:links]
   = meta[:data]

  if meta_links && meta_links[name.to_s]
    extract_many_relationship_from_links(parent, name, options, meta_links[name.to_s])

  elsif data[name.to_s] &&  && ["#{singular}_ids"]
    extract_many_relationship_from_sideload(parent, name, options, response)

  else
    []

  end
end


147
148
149
150
151
152
153
154
155
# File 'lib/ruby_json_api_client/serializers/ams_serializer.rb', line 147

def extract_many_relationship_from_links(parent, name, options, url)
  # since we only have a url pointing to where to pull
  # this info from we need to go back to the store and
  # have it pull this data
  klass_name = options[:class_name] || ActiveSupport::Inflector.classify(name)
  klass = ActiveSupport::Inflector.constantize(klass_name)

  store.load_collection(klass, url)
end

#extract_many_relationship_from_sideload(parent, name, options, response) ⇒ Object



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/ruby_json_api_client/serializers/ams_serializer.rb', line 157

def extract_many_relationship_from_sideload(parent, name, options, response)
  singular = ActiveSupport::Inflector.singularize(name)
  plural = ActiveSupport::Inflector.pluralize(name)
  klass_name = options[:class_name] || ActiveSupport::Inflector.classify(name)
  klass = ActiveSupport::Inflector.constantize(klass_name)
   = parent.meta[:data]

  ids = ["#{singular}_ids"]
  idMap = ids.reduce({}) do |map, id|
    map[id] = true
    map
  end

  extract_many(klass, response, plural)
    .select { |record| idMap[record.id] }
end

#extract_single(klass, id, response) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/ruby_json_api_client/serializers/ams_serializer.rb', line 86

def extract_single(klass, id, response)
  return nil if response.nil?
  name = klass.to_s.underscore
  data = transform(response)

  assert data[name],
    "No key #{name} in json response."

  assert data[name]['id'],
    "No id included in #{name} json data"

  if id
    # we will allow idless loading, but if an id is given we
    # will try to verify it.
    assert data[name]['id'].to_s == id.to_s,
      "Tried to find #{name} with id #{id}, but got #{name} with id #{data[name]['id']}."
  end

  _create_model(klass, data[name])
end

#extract_single_relationship(parent, name, options, response) ⇒ Object



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/ruby_json_api_client/serializers/ams_serializer.rb', line 174

def extract_single_relationship(parent, name, options, response)
  plural = ActiveSupport::Inflector.pluralize(name)
  data = transform(response)
  meta = parent.meta || {}
  meta_links = meta[:links]
   = meta[:data]

  if meta_links && meta_links[name.to_s]
    extract_single_relationship_from_links(parent, name, options, meta_links[name.to_s])

  elsif data[plural.to_s] &&  && ["#{name}_id"]
    extract_single_relationship_from_sideload(parent, name, options, response)

  else
    nil # nothing found, return nil object

  end
end


193
194
195
196
197
198
199
200
# File 'lib/ruby_json_api_client/serializers/ams_serializer.rb', line 193

def extract_single_relationship_from_links(parent, name, options, url)
  klass_name = options[:class_name] || ActiveSupport::Inflector.classify(name)
  klass = ActiveSupport::Inflector.constantize(klass_name)
  meta = parent.meta || {}
   = meta[:data] || {}

  store.load_single(klass, ["#{name}_id"], url)
end

#extract_single_relationship_from_sideload(parent, name, options, response) ⇒ Object



202
203
204
205
206
207
208
209
210
211
# File 'lib/ruby_json_api_client/serializers/ams_serializer.rb', line 202

def extract_single_relationship_from_sideload(parent, name, options, response)
  plural = ActiveSupport::Inflector.pluralize(name)
  klass_name = options[:class_name] || ActiveSupport::Inflector.classify(name)
  klass = ActiveSupport::Inflector.constantize(klass_name)
   = parent.meta[:data]
  id = ["#{name}_id"]

  extract_many(klass, response, plural)
    .detect { |record| record.id == id }
end

#to_data(model) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/ruby_json_api_client/serializers/ams_serializer.rb', line 32

def to_data(model)
  key = model.class.to_s.underscore.downcase
  id_field = model.class._identifier
  data = {}
  data[key] = {}

  # convert fields to json
  model.class.fields.reduce(data[key]) do |result, field|
    result[field] = model.send(field)
    result
  end

  # convert has one relationships to json
  relationships = model.loaded_has_ones || {}
  relationships.reduce(data[key]) do |result, (name, relationship)|
    if relationship.id
      result["#{name}_id"] = relationship.id
    end
    result
  end

  if !model.persisted?
    data[key].delete(id_field) if data[key].has_key?(id_field)
  end

  data
end

#to_json(model) ⇒ Object



60
61
62
# File 'lib/ruby_json_api_client/serializers/ams_serializer.rb', line 60

def to_json(model)
  JSON::generate(to_data(model))
end

#transform(response) ⇒ Object



23
24
25
26
27
28
29
30
# File 'lib/ruby_json_api_client/serializers/ams_serializer.rb', line 23

def transform(response)
  if transformed[response].nil?
    parsed = @json_parsing_method.call(response)
    transformed[response] = parsed
  end

  transformed[response]
end

#transformedObject



19
20
21
# File 'lib/ruby_json_api_client/serializers/ams_serializer.rb', line 19

def transformed
  @transformed ||= {}
end