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