@@ -7,6 +7,10 @@ def find_related_ids(relationship, options)
77 end
88
99 module ClassMethods
10+ def allowed_related_through
11+ @allowed_related_through ||= [ :inverse , :primary ]
12+ end
13+
1014 def default_find_related_through ( polymorphic = false )
1115 if polymorphic
1216 JSONAPI . configuration . default_find_related_through_polymorphic
@@ -125,6 +129,11 @@ def find_fragments(filters, options)
125129 options : options )
126130
127131 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+
128137 # This alias is going to be resolve down to the model's table name and will not actually be an alias
129138 resource_table_alias = resource_klass . _table_name
130139
@@ -195,6 +204,10 @@ def find_fragments(filters, options)
195204 warn "Performance issue detected: `#{ self . name . to_s } .records` returned non-normalized results in `#{ self . name . to_s } .find_fragments`."
196205 end
197206 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+
198211 linkage_fields = [ ]
199212
200213 linkage_relationships . each do |linkage_relationship |
@@ -318,10 +331,16 @@ def _find_related_monomorphic_fragments_through_primary(source_fragments, relati
318331 resource_klass = relationship . resource_klass
319332 linkage_relationships = resource_klass . to_one_relationships_for_linkage ( include_directives [ :include_related ] )
320333
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
325344 end
326345
327346 join_manager = ActiveRelation ::JoinManagerThroughPrimary . new ( resource_klass : self ,
0 commit comments