1+ require 'jsonapi'
2+
13module ActiveModelSerializers
24 module Adapter
35 class JsonApi
46 # NOTE(Experimental):
57 # This is an experimental feature. Both the interface and internals could be subject
68 # to changes.
79 module Deserialization
8- InvalidDocument = Class . new ( ArgumentError )
9-
1010 module_function
1111
1212 # Transform a JSON API document, containing a single data object,
@@ -74,21 +74,21 @@ module Deserialization
7474 #
7575 def parse! ( document , options = { } )
7676 parse ( document , options ) do |invalid_payload , reason |
77- fail InvalidDocument , "Invalid payload (#{ reason } ): #{ invalid_payload } "
77+ fail JSONAPI :: Parser :: InvalidDocument , "Invalid payload (#{ reason } ): #{ invalid_payload } "
7878 end
7979 end
8080
8181 # Same as parse!, but returns an empty hash instead of raising InvalidDocument
8282 # on invalid payloads.
8383 def parse ( document , options = { } )
84- document = document . dup . permit! . to_h if document . is_a? ( ActionController ::Parameters )
85-
86- validate_payload ( document ) do |invalid_document , reason |
87- yield invalid_document , reason if block_given?
88- return { }
89- end
84+ document = JSONAPI . parse ( document , options )
85+ document = document . to_hash
9086
9187 primary_data = document [ 'data' ]
88+
89+ # null data is allowed, as per the JSON API Schema
90+ return { } unless primary_data
91+
9292 attributes = primary_data [ 'attributes' ] || { }
9393 attributes [ 'id' ] = primary_data [ 'id' ] if primary_data [ 'id' ]
9494 relationships = primary_data [ 'relationships' ] || { }
@@ -101,43 +101,11 @@ def parse(document, options = {})
101101 hash . merge! ( parse_relationships ( relationships , options ) )
102102
103103 hash
104- end
105-
106- # Checks whether a payload is compliant with the JSON API spec.
107- #
108- # @api private
109- # rubocop:disable Metrics/CyclomaticComplexity
110- def validate_payload ( payload )
111- unless payload . is_a? ( Hash )
112- yield payload , 'Expected hash'
113- return
114- end
115104
116- primary_data = payload [ 'data' ]
117- unless primary_data . is_a? ( Hash )
118- yield payload , { data : 'Expected hash' }
119- return
120- end
121-
122- attributes = primary_data [ 'attributes' ] || { }
123- unless attributes . is_a? ( Hash )
124- yield payload , { data : { attributes : 'Expected hash or nil' } }
125- return
126- end
127-
128- relationships = primary_data [ 'relationships' ] || { }
129- unless relationships . is_a? ( Hash )
130- yield payload , { data : { relationships : 'Expected hash or nil' } }
131- return
132- end
133-
134- relationships . each do |( key , value ) |
135- unless value . is_a? ( Hash ) && value . key? ( 'data' )
136- yield payload , { data : { relationships : { key => 'Expected hash with :data key' } } }
137- end
138- end
105+ rescue JSONAPI ::Parser ::InvalidDocument
106+ return { } unless block_given?
107+ yield
139108 end
140- # rubocop:enable Metrics/CyclomaticComplexity
141109
142110 # @api private
143111 def filter_fields ( fields , options )
@@ -205,7 +173,7 @@ def parse_relationships(relationships, options)
205173 # @api private
206174 def transform_keys ( hash , options )
207175 transform = options [ :key_transform ] || :underscore
208- KeyTransform . send ( transform , hash )
176+ CaseTransform . send ( transform , hash )
209177 end
210178 end
211179 end
0 commit comments