@@ -9,6 +9,10 @@ def find_related_ids(relationship, options)
9
9
end
10
10
11
11
module ClassMethods
12
+ def allowed_related_through
13
+ @allowed_related_through ||= [ :inverse , :primary ]
14
+ end
15
+
12
16
def default_find_related_through ( polymorphic = false )
13
17
if polymorphic
14
18
JSONAPI . configuration . default_find_related_through_polymorphic
@@ -127,6 +131,11 @@ def find_fragments(filters, options)
127
131
options : options )
128
132
129
133
if options [ :cache ]
134
+ # When using caching the a two step process is used. First the records ids are retrieved and then the
135
+ # records are retrieved using the ids. Then the ids are used to query the database again to get the
136
+ # cache misses. In the second phase the records are not sorted or paginated and the `records_for_populate`
137
+ # method is used to ensure any dependent includes or custom database fields are calculated.
138
+
130
139
# This alias is going to be resolve down to the model's table name and will not actually be an alias
131
140
resource_table_alias = resource_klass . _table_name
132
141
@@ -197,6 +206,10 @@ def find_fragments(filters, options)
197
206
warn "Performance issue detected: `#{ self . name . to_s } .records` returned non-normalized results in `#{ self . name . to_s } .find_fragments`."
198
207
end
199
208
else
209
+ # When not using caching resources can be generated after querying. The `records_for_populate`
210
+ # method is merged in to ensure any dependent includes or custom database fields are calculated.
211
+ records = records . merge ( records_for_populate ( options ) )
212
+
200
213
linkage_fields = [ ]
201
214
202
215
linkage_relationships . each do |linkage_relationship |
@@ -320,10 +333,16 @@ def _find_related_monomorphic_fragments_through_primary(source_fragments, relati
320
333
resource_klass = relationship . resource_klass
321
334
linkage_relationships = resource_klass . to_one_relationships_for_linkage ( include_directives [ :include_related ] )
322
335
323
- sort_criteria = [ ]
324
- options [ :sort_criteria ] . try ( :each ) do |sort |
325
- field = sort [ :field ] . to_s == 'id' ? resource_klass . _primary_key : sort [ :field ]
326
- sort_criteria << { field : field , direction : sort [ :direction ] }
336
+ # Do not sort the related_fragments. This can be keyed off `connect_source_identity` to indicate whether this
337
+ # is a related resource primary step vs. an include step.
338
+ sort_related_fragments = !connect_source_identity
339
+
340
+ if sort_related_fragments
341
+ sort_criteria = [ ]
342
+ options [ :sort_criteria ] . try ( :each ) do |sort |
343
+ field = sort [ :field ] . to_s == 'id' ? resource_klass . _primary_key : sort [ :field ]
344
+ sort_criteria << { field : field , direction : sort [ :direction ] }
345
+ end
327
346
end
328
347
329
348
join_manager = ActiveRelation ::JoinManagerThroughPrimary . new ( resource_klass : self ,
0 commit comments