Skip to content

Commit 99268a8

Browse files
committed
Track and select sort fields to fix postgres sql generation error
1 parent 864e810 commit 99268a8

File tree

2 files changed

+28
-14
lines changed

2 files changed

+28
-14
lines changed

lib/jsonapi/active_relation_resource.rb

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,11 @@ def find_fragments(filters, options = {})
153153
pluck_fields << Arel.sql("#{concat_table_field(resource_table_alias, model_field[:name])} AS #{resource_table_alias}_#{model_field[:name]}")
154154
end
155155

156+
sort_fields = options.dig(:_relation_helper_options, :sort_fields)
157+
sort_fields.try(:each) do |field|
158+
pluck_fields << Arel.sql(field)
159+
end
160+
156161
fragments = {}
157162
rows = records.pluck(*pluck_fields)
158163
rows.each do |row|
@@ -445,6 +450,11 @@ def find_related_monomorphic_fragments(source_rids, relationship, options, conne
445450
pluck_fields << Arel.sql("#{concat_table_field(resource_table_alias, model_field[:name])} AS #{resource_table_alias}_#{model_field[:name]}")
446451
end
447452

453+
sort_fields = options.dig(:_relation_helper_options, :sort_fields)
454+
sort_fields.try(:each) do |field|
455+
pluck_fields << Arel.sql(field)
456+
end
457+
448458
fragments = {}
449459
rows = records.distinct.pluck(*pluck_fields)
450460
rows.each do |row|
@@ -680,24 +690,23 @@ def apply_request_settings_to_records(records:,
680690
paginator: nil,
681691
options: {})
682692

683-
opts = options.dup
684-
records = resource_klass.apply_joins(records, join_manager, opts)
693+
options[:_relation_helper_options] = { join_manager: join_manager, sort_fields: [] }
694+
695+
records = resource_klass.apply_joins(records, join_manager, options)
685696

686697
if primary_keys
687698
records = records.where(_primary_key => primary_keys)
688699
end
689700

690-
opts[:join_manager] = join_manager
691-
692701
unless filters.empty?
693-
records = resource_klass.filter_records(records, filters, opts)
702+
records = resource_klass.filter_records(records, filters, options)
694703
end
695704

696705
if sort_primary
697706
records = records.order(_primary_key => :asc)
698707
else
699708
order_options = resource_klass.construct_order_options(sort_criteria)
700-
records = resource_klass.sort_records(records, order_options, opts)
709+
records = resource_klass.sort_records(records, order_options, options)
701710
end
702711

703712
if paginator
@@ -731,12 +740,16 @@ def apply_single_sort(records, field, direction, options)
731740

732741
strategy = _allowed_sort.fetch(field.to_sym, {})[:apply]
733742

743+
options[:_relation_helper_options] ||= {}
744+
options[:_relation_helper_options][:sort_fields] ||= []
745+
734746
if strategy
735747
records = call_method_or_proc(strategy, records, direction, context)
736748
else
737-
join_manager = options[:join_manager]
738-
739-
records = records.order(Arel.sql("#{get_aliased_field(field, join_manager)} #{direction}"))
749+
join_manager = options.dig(:_relation_helper_options, :join_manager)
750+
sort_field = join_manager ? get_aliased_field(field, join_manager) : field
751+
options[:_relation_helper_options][:sort_fields].push("#{sort_field}")
752+
records = records.order(Arel.sql("#{sort_field} #{direction}"))
740753
end
741754
records
742755
end
@@ -825,8 +838,9 @@ def apply_filter(records, filter, value, options = {})
825838
if strategy
826839
records = call_method_or_proc(strategy, records, value, options)
827840
else
828-
join_manager = options[:join_manager]
829-
records = records.where(Arel.sql(get_aliased_field(filter, join_manager)) => value)
841+
join_manager = options.dig(:_relation_helper_options, :join_manager)
842+
field = join_manager ? get_aliased_field(filter, join_manager) : filter
843+
records = records.where(Arel.sql(field) => value)
830844
end
831845

832846
records

test/fixtures/active_record.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1650,7 +1650,7 @@ class CraterResource < JSONAPI::Resource
16501650

16511651
filter :description, apply: -> (records, value, options) {
16521652
fail "context not set" unless options[:context][:current_user] != nil && options[:context][:current_user] == $test_user
1653-
records.where(concat_table_field(options[:join_manager].source_join_details[:alias], :description) => value)
1653+
records.where(concat_table_field(options.dig(:_relation_helper_options, :join_manager).source_join_details[:alias], :description) => value)
16541654
}
16551655

16561656
def self.verify_key(key, context = nil)
@@ -1694,7 +1694,7 @@ class PictureResource < JSONAPI::Resource
16941694
has_one :file_properties, inverse_relationship: :fileable, :foreign_key_on => :related, polymorphic: true
16951695

16961696
filter 'imageable.name', perform_joins: true, apply: -> (records, value, options) {
1697-
join_manager = options[:join_manager]
1697+
join_manager = options.dig(:_relation_helper_options, :join_manager)
16981698
relationship = _relationship(:imageable)
16991699
or_parts = relationship.resource_types.collect do |type|
17001700
table_alias = join_manager.join_details_by_polymorphic_relationship(relationship, type)[:alias]
@@ -2038,7 +2038,7 @@ class AuthorResource < JSONAPI::Resource
20382038
relationship :author_detail, to: :one, foreign_key_on: :related
20392039

20402040
filter :name, apply: lambda { |records, value, options|
2041-
table_alias = options[:join_manager].source_join_details[:alias]
2041+
table_alias = options.dig(:_relation_helper_options, :join_manager).source_join_details[:alias]
20422042
t = Arel::Table.new(:people, as: table_alias)
20432043
records.where(t[:name].matches("%#{value[0]}%"))
20442044
}

0 commit comments

Comments
 (0)