1- require 'jsonapi/include_directive'
1+ require 'jsonapi/renderer/error_document'
2+ require 'jsonapi/renderer/success_document'
23
34module JSONAPI
4- class Renderer
5- def initialize ( resources , options = { } )
6- @resources = resources
7- @errors = options [ :errors ] || false
8- @meta = options [ :meta ] || nil
9- @links = options [ :links ] || { }
10- @fields = options [ :fields ] || { }
11- # NOTE(beauby): Room for some nifty defaults on those.
12- @jsonapi = options [ :jsonapi_object ] || nil
13- @include = JSONAPI ::IncludeDirective . new ( options [ :include ] || { } )
14- end
15-
16- def as_json
17- return @json unless @json . nil?
18-
19- process_resources
20- @json = { }
21-
22- if @errors
23- @json [ :errors ] = @resources . map ( &:as_jsonapi )
24- else
25- @json [ :data ] = @resources . respond_to? ( :each ) ? @primary : @primary [ 0 ]
26- @json [ :included ] = @included if @included . any?
27- end
28- @json [ :links ] = @links if @links . any?
29- @json [ :meta ] = @meta unless @meta . nil?
30- @json [ :jsonapi ] = @jsonapi unless @jsonapi . nil?
31-
32- @json
33- end
34-
35- private
36-
37- def process_resources
38- @primary = [ ]
39- @included = [ ]
40- @hashes = { }
41- @processed = Set . new # NOTE(beauby): Set of [type, id, prefix].
42- @queue = [ ]
43-
44- Array ( @resources ) . each do |res |
45- process_resource ( res , '' , @include , true )
46- @processed . add ( [ res . jsonapi_type , res . jsonapi_id , '' ] )
47- end
48- until @queue . empty?
49- res , prefix , include_dir = @queue . pop
50- process_resource ( res , prefix , include_dir , false )
51- end
52- end
53-
54- def merge_resources! ( a , b )
55- b [ :relationships ] . each do |name , rel |
56- a [ :relationships ] [ name ] [ :data ] ||= rel [ :data ] if rel . key? ( :data )
57- ( a [ :relationships ] [ name ] [ :links ] ||= { } )
58- . merge! ( rel [ :links ] ) if rel . key? ( :links )
59- end
60- end
61-
62- def process_resource ( res , prefix , include_dir , is_primary )
63- ri = [ res . jsonapi_type , res . jsonapi_id ]
64- hash = res . as_jsonapi ( fields : @fields [ res . jsonapi_type . to_sym ] ,
65- include : include_dir . keys )
66- if @hashes . key? ( ri )
67- merge_resources! ( @hashes [ ri ] , hash )
68- else
69- ( is_primary ? @primary : @included ) << ( @hashes [ ri ] = hash )
70- end
71- process_relationships ( res , prefix , include_dir )
72- end
73-
74- def process_relationships ( res , prefix , include_dir )
75- res . jsonapi_related ( include_dir . keys ) . each do |key , data |
76- Array ( data ) . each do |child_res |
77- next if child_res . nil?
78- child_prefix = "#{ prefix } .#{ key } "
79- next unless @processed . add? ( [ child_res . jsonapi_type ,
80- child_res . jsonapi_id ,
81- child_prefix ] )
82- @queue << [ child_res , child_prefix , include_dir [ key ] ]
83- end
84- end
85- end
86- end
87-
885 module_function
896
907 # Render a success JSON API document.
@@ -102,7 +19,7 @@ def process_relationships(res, prefix, include_dir)
10219 # @option [Hash] links Top-level links to be included.
10320 # @option [Hash] jsonapi_object JSON API object.
10421 def render ( resources , options = { } )
105- Renderer . new ( resources , options ) . as_json
22+ Renderer :: SuccessDocument . new ( resources , options ) . as_json
10623 end
10724
10825 # Render an error JSON API document.
@@ -114,6 +31,6 @@ def render(resources, options = {})
11431 # @option [Hash] links Top-level links to be included.
11532 # @option [Hash] jsonapi_object JSON API object.
11633 def render_errors ( errors )
117- Renderer . new ( errors , errors : true ) . as_json
34+ Renderer :: ErrorDocument . new ( errors ) . as_json
11835 end
11936end
0 commit comments