Skip to content

Commit 216cb70

Browse files
committed
Fix apply sort
1 parent 4b75036 commit 216cb70

File tree

2 files changed

+44
-43
lines changed

2 files changed

+44
-43
lines changed

lib/jsonapi/active_record_accessor.rb

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -210,28 +210,26 @@ def apply_pagination(records, paginator, order_options)
210210
end
211211

212212
def apply_sort(records, order_options, context = {})
213-
if defined?(_resource_klass.apply_sort)
214-
_resource_klass.apply_sort(records, order_options, context)
215-
else
216-
if order_options.any?
217-
order_options.each_pair do |field, direction|
218-
if field.to_s.include?(".")
219-
*model_names, column_name = field.split(".")
220-
221-
associations = _lookup_association_chain([records.model.to_s, *model_names])
222-
joins_query = _build_joins([records.model, *associations])
223-
224-
# _sorting is appended to avoid name clashes with manual joins eg. overridden filters
225-
order_by_query = "#{associations.last.name}_sorting.#{column_name} #{direction}"
226-
records = records.joins(joins_query).order(order_by_query)
227-
else
228-
records = records.order(field => direction)
229-
end
213+
if order_options.any?
214+
order_options.each_pair do |field, direction|
215+
if field.to_s.include?(".")
216+
*model_names, column_name = field.split(".")
217+
218+
associations = _lookup_association_chain([records.model.to_s, *model_names])
219+
joins_query = _build_joins([records.model, *associations])
220+
221+
# _sorting is appended to avoid name clashes with manual joins eg. overridden filters
222+
order_by_query = "#{associations.last.name}_sorting.#{column_name} #{direction}"
223+
records = records.joins(joins_query).order(order_by_query)
224+
else
225+
records = records.order(field => direction)
230226
end
231227
end
232-
233-
records
234228
end
229+
230+
return records unless defined?(_resource_klass.apply_sort)
231+
custom_sort = _resource_klass.apply_sort(records, order_options, context)
232+
custom_sort.nil? ? records : custom_sort
235233
end
236234

237235
def _lookup_association_chain(model_names)
@@ -472,7 +470,7 @@ def preload_included_fragments(src_res_class, resource_pile, path, serializer, o
472470
next unless src_res
473471
fragment = target_resources[tgt_id]
474472
next unless fragment
475-
src_res.preloaded_fragments[serialized_rel_name][tgt_id] = fragment
473+
src_res.preloaded_fragments[serialized_rel_name][tgt_id] = fragment
476474
end
477475
end
478476

test/unit/resource/resource_test.rb

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -378,12 +378,36 @@ def apply_filters(records, filters, options)
378378
end
379379
end
380380

381+
def test_custom_sorting
382+
post_resource = PostResource.new(Post.find(1), nil)
383+
comment_ids = post_resource.comments.map{|c| c._model.id }
384+
assert_equal [1,2], comment_ids
385+
386+
# define apply_sort method on post resource that will never sort
387+
PostResource.instance_eval do
388+
def apply_sort(records, criteria, context = {})
389+
if criteria.key?('name')
390+
# this sort will never occure
391+
records.order('name asc')
392+
end
393+
end
394+
end
395+
396+
sorted_comment_ids = post_resource.comments(sort_criteria: [{ field: 'id', direction: :desc}]).map{|c| c._model.id }
397+
assert_equal [2,1], sorted_comment_ids
398+
ensure
399+
# reset method to original implementation
400+
PostResource.instance_eval do
401+
undef :apply_sort
402+
end
403+
end
404+
381405
def test_to_many_relationship_sorts
382406
post_resource = PostResource.new(Post.find(1), nil)
383407
comment_ids = post_resource.comments.map{|c| c._model.id }
384408
assert_equal [1,2], comment_ids
385409

386-
# define apply_filters method on post resource to sort descending
410+
# define apply_sort method on post resource to sort descending
387411
PostResource.instance_eval do
388412
def apply_sort(records, criteria, context = {})
389413
# :nocov:
@@ -399,28 +423,7 @@ def apply_sort(records, criteria, context = {})
399423
ensure
400424
# reset method to original implementation
401425
PostResource.instance_eval do
402-
def apply_sort(records, order_options, _context = {})
403-
# :nocov:
404-
if order_options.any?
405-
order_options.each_pair do |field, direction|
406-
if field.to_s.include?(".")
407-
*model_names, column_name = field.split(".")
408-
409-
associations = _lookup_association_chain([records.model.to_s, *model_names])
410-
joins_query = _record_accessor._build_joins([records.model, *associations])
411-
412-
# _sorting is appended to avoid name clashes with manual joins eg. overriden filters
413-
order_by_query = "#{associations.last.name}_sorting.#{column_name} #{direction}"
414-
records = records.joins(joins_query).order(order_by_query)
415-
else
416-
records = records.order(field => direction)
417-
end
418-
end
419-
end
420-
421-
records
422-
# :nocov:
423-
end
426+
undef :apply_sort
424427
end
425428
end
426429

0 commit comments

Comments
 (0)