@@ -2,6 +2,10 @@ module JSONAPI
2
2
class ActiveRelationResource < BasicResource
3
3
root_resource
4
4
5
+ def find_related_ids ( relationship , options = { } )
6
+ self . class . find_related_fragments ( [ self ] , relationship . name , options ) . keys . collect { |rid | rid . id }
7
+ end
8
+
5
9
class << self
6
10
# Finds Resources using the `filters`. Pagination and sort options are used when provided
7
11
#
@@ -90,8 +94,11 @@ def find_to_populate_by_keys(keys, options = {})
90
94
# the ResourceInstances matching the filters, sorting, and pagination rules along with any request
91
95
# additional_field values
92
96
def find_fragments ( filters , options = { } )
93
- include_directives = options [ :include_directives ] ? options [ :include_directives ] . include_directives : { }
97
+ include_directives = options . fetch ( :include_directives , { } )
94
98
resource_klass = self
99
+
100
+ fragments = { }
101
+
95
102
linkage_relationships = to_one_relationships_for_linkage ( include_directives [ :include_related ] )
96
103
97
104
sort_criteria = options . fetch ( :sort_criteria ) { [ ] }
@@ -129,18 +136,26 @@ def find_fragments(filters, options = {})
129
136
if linkage_relationship . polymorphic? && linkage_relationship . belongs_to?
130
137
linkage_relationship . resource_types . each do |resource_type |
131
138
klass = resource_klass_for ( resource_type )
132
- linkage_fields << { relationship_name : name , resource_klass : klass }
133
-
134
139
linkage_table_alias = join_manager . join_details_by_polymorphic_relationship ( linkage_relationship , resource_type ) [ :alias ]
135
140
primary_key = klass . _primary_key
141
+
142
+ linkage_fields << { relationship_name : name ,
143
+ resource_klass : klass ,
144
+ field : "#{ concat_table_field ( linkage_table_alias , primary_key ) } AS #{ linkage_table_alias } _#{ primary_key } " ,
145
+ alias : "#{ linkage_table_alias } _#{ primary_key } " }
146
+
136
147
pluck_fields << Arel . sql ( "#{ concat_table_field ( linkage_table_alias , primary_key ) } AS #{ linkage_table_alias } _#{ primary_key } " )
137
148
end
138
149
else
139
150
klass = linkage_relationship . resource_klass
140
- linkage_fields << { relationship_name : name , resource_klass : klass }
141
-
142
151
linkage_table_alias = join_manager . join_details_by_relationship ( linkage_relationship ) [ :alias ]
143
152
primary_key = klass . _primary_key
153
+
154
+ linkage_fields << { relationship_name : name ,
155
+ resource_klass : klass ,
156
+ field : "#{ concat_table_field ( linkage_table_alias , primary_key ) } AS #{ linkage_table_alias } _#{ primary_key } " ,
157
+ alias : "#{ linkage_table_alias } _#{ primary_key } " }
158
+
144
159
pluck_fields << Arel . sql ( "#{ concat_table_field ( linkage_table_alias , primary_key ) } AS #{ linkage_table_alias } _#{ primary_key } " )
145
160
end
146
161
end
@@ -158,7 +173,6 @@ def find_fragments(filters, options = {})
158
173
pluck_fields << Arel . sql ( field )
159
174
end
160
175
161
- fragments = { }
162
176
rows = records . pluck ( *pluck_fields )
163
177
rows . each do |row |
164
178
rid = JSONAPI ::ResourceIdentity . new ( resource_klass , pluck_fields . length == 1 ? row : row [ 0 ] )
@@ -204,23 +218,23 @@ def find_fragments(filters, options = {})
204
218
# @return [Hash{ResourceIdentity => {identity: => ResourceIdentity, cache: cache_field, attributes: => {name => value}, related: {relationship_name: [] }}}]
205
219
# the ResourceInstances matching the filters, sorting, and pagination rules along with any request
206
220
# additional_field values
207
- def find_related_fragments ( source_rids , relationship_name , options = { } )
221
+ def find_related_fragments ( source , relationship_name , options = { } )
208
222
relationship = _relationship ( relationship_name )
209
223
210
224
if relationship . polymorphic? # && relationship.foreign_key_on == :self
211
- find_related_polymorphic_fragments ( source_rids , relationship , options , false )
225
+ find_related_polymorphic_fragments ( source , relationship , options , false )
212
226
else
213
- find_related_monomorphic_fragments ( source_rids , relationship , options , false )
227
+ find_related_monomorphic_fragments ( source , relationship , options , false )
214
228
end
215
229
end
216
230
217
- def find_included_fragments ( source_rids , relationship_name , options )
231
+ def find_included_fragments ( source , relationship_name , options )
218
232
relationship = _relationship ( relationship_name )
219
233
220
234
if relationship . polymorphic? # && relationship.foreign_key_on == :self
221
- find_related_polymorphic_fragments ( source_rids , relationship , options , true )
235
+ find_related_polymorphic_fragments ( source , relationship , options , true )
222
236
else
223
- find_related_monomorphic_fragments ( source_rids , relationship , options , true )
237
+ find_related_monomorphic_fragments ( source , relationship , options , true )
224
238
end
225
239
end
226
240
@@ -231,7 +245,7 @@ def find_included_fragments(source_rids, relationship_name, options)
231
245
# @option options [Hash] :context The context of the request, set in the controller
232
246
#
233
247
# @return [Integer] the count
234
- def count_related ( source_rid , relationship_name , options = { } )
248
+ def count_related ( source_resource , relationship_name , options = { } )
235
249
relationship = _relationship ( relationship_name )
236
250
related_klass = relationship . resource_klass
237
251
@@ -244,7 +258,7 @@ def count_related(source_rid, relationship_name, options = {})
244
258
245
259
records = apply_request_settings_to_records ( records : records ( options ) ,
246
260
resource_klass : related_klass ,
247
- primary_keys : source_rid . id ,
261
+ primary_keys : source_resource . id ,
248
262
join_manager : join_manager ,
249
263
filters : filters ,
250
264
options : options )
@@ -375,11 +389,11 @@ def find_records_by_keys(keys, options = {})
375
389
apply_request_settings_to_records ( records : records ( options ) , primary_keys : keys , options : options )
376
390
end
377
391
378
- def find_related_monomorphic_fragments ( source_rids , relationship , options , connect_source_identity )
392
+ def find_related_monomorphic_fragments ( source_fragments , relationship , options , connect_source_identity )
379
393
filters = options . fetch ( :filters , { } )
380
- source_ids = source_rids . collect { |rid | rid . id }
394
+ source_ids = source_fragments . collect { |item | item . identity . id }
381
395
382
- include_directives = options [ :include_directives ] ? options [ :include_directives ] . include_directives : { }
396
+ include_directives = options . fetch ( :include_directives , { } )
383
397
resource_klass = relationship . resource_klass
384
398
linkage_relationships = resource_klass . to_one_relationships_for_linkage ( include_directives [ :include_related ] )
385
399
@@ -501,12 +515,12 @@ def find_related_monomorphic_fragments(source_rids, relationship, options, conne
501
515
502
516
# Gets resource identities where the related resource is polymorphic and the resource type and id
503
517
# are stored on the primary resources. Cache fields will always be on the related resources.
504
- def find_related_polymorphic_fragments ( source_rids , relationship , options , connect_source_identity )
518
+ def find_related_polymorphic_fragments ( source_fragments , relationship , options , connect_source_identity )
505
519
filters = options . fetch ( :filters , { } )
506
- source_ids = source_rids . collect { |rid | rid . id }
520
+ source_ids = source_fragments . collect { |item | item . identity . id }
507
521
508
522
resource_klass = relationship . resource_klass
509
- include_directives = options [ :include_directives ] ? options [ :include_directives ] . include_directives : { }
523
+ include_directives = options . fetch ( :include_directives , { } )
510
524
511
525
linkage_relationships = [ ]
512
526
0 commit comments