@@ -15,6 +15,11 @@ module Formatters
1515 # @option options [JSONAPI::Resource] resource: it tells the formatter which resource
1616 # class to be used rather than use an infered one (default behaviour)
1717 #
18+ # @option options [JSONAPI::Resource] source_resource: it tells the formatter that this response is from a related resource
19+ # and the result should be interpreted as a related resources response
20+ #
21+ # @option options [String, Symbol] relationship_type: it tells that the formatter which relationship the data is from
22+ #
1823 # @option options [ActiveRecord::Base] model: ActiveRecord model class to be instantiated
1924 # when a Hash or Array of Hashes is passed as the "object" argument
2025 #
@@ -51,7 +56,7 @@ def jsonapi_format(object, options = {})
5156 # @api public
5257 def jsonapi_format_errors ( object )
5358 if active_record_obj? ( object )
54- object = JSONAPI ::Utils ::Exceptions ::ActiveRecord . new ( object , @request . resource_klass , context )
59+ object = JSONAPI ::Utils ::Exceptions ::ActiveRecord . new ( object , @request . resource_klass , context )
5560 end
5661 errors = object . respond_to? ( :errors ) ? object . errors : object
5762 JSONAPI ::Utils ::Support ::Error . sanitize ( errors ) . uniq
@@ -84,6 +89,11 @@ def active_record_obj?(object)
8489 # @option options [JSONAPI::Resource] resource: it tells the builder which resource
8590 # class to be used rather than use an infered one (default behaviour)
8691 #
92+ # @option options [ActiveRecord::Base, JSONAPI::Resource] source: it tells the builder that this response is from a related resource
93+ # and the result should be interpreted as a related resources response
94+ #
95+ # @option options [String, Symbol] relationship: it tells that the builder which relationship the data is from
96+ #
8797 # @option options [Integer] count: if it's rendering a collection of resources, the default
8898 # gem's counting method can be bypassed by the use of this options. It's shows then the total
8999 # records resulting from that request and also calculates the pagination.
@@ -96,7 +106,19 @@ def build_response_document(object, options)
96106
97107 if object . respond_to? ( :to_ary )
98108 records = build_collection ( object , options )
99- results . add_result ( JSONAPI ::ResourcesOperationResult . new ( :ok , records , result_options ( object , options ) ) )
109+
110+ if params [ :source ] . present? && params [ :relationship ] . present?
111+ source_resource = turn_source_into_resource ( options [ :source ] , options )
112+ relationship_type = get_source_relationship ( options )
113+
114+ results . add_result ( JSONAPI ::RelatedResourcesOperationResult . new ( :ok ,
115+ source_resource ,
116+ relationship_type ,
117+ records ,
118+ result_options ( object , options ) ) )
119+ else
120+ results . add_result ( JSONAPI ::ResourcesOperationResult . new ( :ok , records , result_options ( object , options ) ) )
121+ end
100122 else
101123 record = turn_into_resource ( object , options )
102124 results . add_result ( JSONAPI ::ResourceOperationResult . new ( :ok , record ) )
@@ -171,6 +193,34 @@ def turn_into_resource(record, options)
171193 end
172194 end
173195
196+ # Get JSONAPI::Resource for source object
197+ # @option options [JSONAPI::Resource] resource: it tells which resource
198+ # class to be used rather than use an infered one (default behaviour)
199+ # @return [JSONAPI::Resource]
200+ #
201+ # @api private
202+ def turn_source_into_resource ( source , options )
203+ if source . kind_of? JSONAPI ::Resource
204+ source
205+ else
206+ @request . source_klass . new ( source , context )
207+ end
208+ end
209+
210+ # Get relationship type of source object
211+ # @option options [Symbol] relationship: it tells which relationship
212+ # to be used rather than use an infered one (default behaviour)
213+ # @return [Symbol]
214+ #
215+ # @api private
216+ def get_source_relationship ( options )
217+ if options [ :relationship ] . present?
218+ options [ :relationship ] . to_sym
219+ else
220+ params [ :relationship ] . to_sym || @request . resource_klass . _type
221+ end
222+ end
223+
174224 # Apply some result options like pagination params and record count to collection responses.
175225 #
176226 # @param records [ActiveRecord::Relation, Hash, Array<Hash>]
0 commit comments