@@ -7,58 +7,78 @@ def initialize(resources, include, fields)
77 @resources = resources
88 @include = include
99 @fields = fields
10- @primary = [ ]
11- @included = [ ]
12- @hashes = { }
13- @queue = [ ]
14- @processed = Set . new # NOTE(beauby): Set of [type, id, prefix].
1510 end
1611
1712 def process
18- @resources . each do |res |
19- process_resource ( res , '' , @include , true )
20- @processed . add ( [ res . jsonapi_type , res . jsonapi_id , '' ] )
21- end
22- until @queue . empty?
23- res , prefix , include_dir = @queue . pop
24- process_resource ( res , prefix , include_dir , false )
25- end
13+ traverse_resources
14+ process_resources
2615
2716 [ @primary , @included ]
2817 end
2918
3019 private
3120
32- def merge_resources! ( a , b )
33- b [ :relationships ] . each do |name , rel |
34- a [ :relationships ] [ name ] [ :data ] ||= rel [ :data ] if rel . key? ( :data )
35- if rel . key? ( :links )
36- ( a [ :relationships ] [ name ] [ :links ] ||= { } ) . merge! ( rel [ :links ] )
37- end
21+ def traverse_resources
22+ @traversed = Set . new # [type, id, prefix]
23+ @include_rels = { } # [type, id => Set]
24+ @queue = [ ]
25+ @primary = [ ]
26+ @included = [ ]
27+
28+ initialize_queue
29+ traverse_queue
30+ end
31+
32+ def initialize_queue
33+ @resources . each do |res |
34+ @traversed . add ( [ res . jsonapi_type , res . jsonapi_id , '' ] )
35+ traverse_resource ( res , @include . keys , true )
36+ enqueue_related_resources ( res , '' , @include )
3837 end
3938 end
4039
41- def process_resource ( res , prefix , include_dir , is_primary )
40+ def traverse_queue
41+ until @queue . empty?
42+ res , prefix , include_dir = @queue . pop
43+ traverse_resource ( res , include_dir . keys , false )
44+ enqueue_related_resources ( res , prefix , include_dir )
45+ end
46+ end
47+
48+ def traverse_resource ( res , include_keys , primary )
4249 ri = [ res . jsonapi_type , res . jsonapi_id ]
43- hash = res . as_jsonapi ( fields : @fields [ res . jsonapi_type . to_sym ] ,
44- include : include_dir . keys )
45- if @hashes . key? ( ri )
46- merge_resources! ( @hashes [ ri ] , hash )
50+ if @include_rels . include? ( ri )
51+ @include_rels [ ri ] . merge! ( include_keys )
4752 else
48- ( is_primary ? @primary : @included ) << ( @hashes [ ri ] = hash )
53+ @include_rels [ ri ] = Set . new ( include_keys )
54+ ( primary ? @primary : @included ) << res
4955 end
50- process_relationships ( res , prefix , include_dir )
5156 end
5257
53- def process_relationships ( res , prefix , include_dir )
58+ def enqueue_related_resources ( res , prefix , include_dir )
5459 res . jsonapi_related ( include_dir . keys ) . each do |key , data |
5560 data . each do |child_res |
5661 next if child_res . nil?
5762 child_prefix = "#{ prefix } .#{ key } "
58- next unless @processed . add? ( [ child_res . jsonapi_type ,
59- child_res . jsonapi_id ,
60- child_prefix ] )
61- @queue << [ child_res , child_prefix , include_dir [ key ] ]
63+ enqueue_resource ( child_res , child_prefix , include_dir [ key ] )
64+ end
65+ end
66+ end
67+
68+ def enqueue_resource ( res , prefix , include_dir )
69+ return unless @traversed . add? ( [ res . jsonapi_type ,
70+ res . jsonapi_id ,
71+ prefix ] )
72+ @queue << [ res , prefix , include_dir ]
73+ end
74+
75+ def process_resources
76+ [ @primary , @included ] . each do |resources |
77+ resources . map! do |res |
78+ ri = [ res . jsonapi_type , res . jsonapi_id ]
79+ include_dir = @include_rels [ ri ]
80+ fields = @fields [ res . jsonapi_type . to_sym ]
81+ res . as_jsonapi ( include : include_dir , fields : fields )
6282 end
6383 end
6484 end
0 commit comments