Skip to content

Commit

Permalink
Track and select sort fields to fix postgres sql generation error
Browse files Browse the repository at this point in the history
  • Loading branch information
lgebhardt committed Oct 9, 2019
1 parent 864e810 commit 99268a8
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 14 deletions.
36 changes: 25 additions & 11 deletions lib/jsonapi/active_relation_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@ def find_fragments(filters, options = {})
pluck_fields << Arel.sql("#{concat_table_field(resource_table_alias, model_field[:name])} AS #{resource_table_alias}_#{model_field[:name]}")
end

sort_fields = options.dig(:_relation_helper_options, :sort_fields)
sort_fields.try(:each) do |field|
pluck_fields << Arel.sql(field)
end

fragments = {}
rows = records.pluck(*pluck_fields)
rows.each do |row|
Expand Down Expand Up @@ -445,6 +450,11 @@ def find_related_monomorphic_fragments(source_rids, relationship, options, conne
pluck_fields << Arel.sql("#{concat_table_field(resource_table_alias, model_field[:name])} AS #{resource_table_alias}_#{model_field[:name]}")
end

sort_fields = options.dig(:_relation_helper_options, :sort_fields)
sort_fields.try(:each) do |field|
pluck_fields << Arel.sql(field)
end

fragments = {}
rows = records.distinct.pluck(*pluck_fields)
rows.each do |row|
Expand Down Expand Up @@ -680,24 +690,23 @@ def apply_request_settings_to_records(records:,
paginator: nil,
options: {})

opts = options.dup
records = resource_klass.apply_joins(records, join_manager, opts)
options[:_relation_helper_options] = { join_manager: join_manager, sort_fields: [] }

records = resource_klass.apply_joins(records, join_manager, options)

if primary_keys
records = records.where(_primary_key => primary_keys)
end

opts[:join_manager] = join_manager

unless filters.empty?
records = resource_klass.filter_records(records, filters, opts)
records = resource_klass.filter_records(records, filters, options)
end

if sort_primary
records = records.order(_primary_key => :asc)
else
order_options = resource_klass.construct_order_options(sort_criteria)
records = resource_klass.sort_records(records, order_options, opts)
records = resource_klass.sort_records(records, order_options, options)
end

if paginator
Expand Down Expand Up @@ -731,12 +740,16 @@ def apply_single_sort(records, field, direction, options)

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

options[:_relation_helper_options] ||= {}
options[:_relation_helper_options][:sort_fields] ||= []

if strategy
records = call_method_or_proc(strategy, records, direction, context)
else
join_manager = options[:join_manager]

records = records.order(Arel.sql("#{get_aliased_field(field, join_manager)} #{direction}"))
join_manager = options.dig(:_relation_helper_options, :join_manager)
sort_field = join_manager ? get_aliased_field(field, join_manager) : field
options[:_relation_helper_options][:sort_fields].push("#{sort_field}")
records = records.order(Arel.sql("#{sort_field} #{direction}"))
end
records
end
Expand Down Expand Up @@ -825,8 +838,9 @@ def apply_filter(records, filter, value, options = {})
if strategy
records = call_method_or_proc(strategy, records, value, options)
else
join_manager = options[:join_manager]
records = records.where(Arel.sql(get_aliased_field(filter, join_manager)) => value)
join_manager = options.dig(:_relation_helper_options, :join_manager)
field = join_manager ? get_aliased_field(filter, join_manager) : filter
records = records.where(Arel.sql(field) => value)
end

records
Expand Down
6 changes: 3 additions & 3 deletions test/fixtures/active_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1650,7 +1650,7 @@ class CraterResource < JSONAPI::Resource

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

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

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

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

0 comments on commit 99268a8

Please sign in to comment.