Skip to content

Commit 87467eb

Browse files
senid231lgebhardt
authored andcommitted
fix regression in 0.9.5 server error when using filter with dot in name and custom applier
Closes gh-1215
1 parent ace72f8 commit 87467eb

File tree

4 files changed

+53
-21
lines changed

4 files changed

+53
-21
lines changed

lib/jsonapi/request_parser.rb

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -251,34 +251,41 @@ def parse_filters(filters)
251251
end
252252

253253
filters.each do |key, value|
254-
filter_method, included_resource_name =
255-
key.to_s.split('.').map { |k| unformat_key(k) }.reverse
256254

257-
if included_resource_name
258-
relationship = resource_klass._relationship(included_resource_name || '')
255+
unformatted_key = unformat_key(key)
256+
if resource_klass._allowed_filter?(unformatted_key)
257+
@filters[unformatted_key] = value
258+
elsif unformatted_key.to_s.include?('.')
259+
parse_relationship_filter(unformatted_key, value)
260+
else
261+
return @errors.concat(Exceptions::FilterNotAllowed.new(unformatted_key).errors)
262+
end
263+
end
264+
end
259265

260-
unless relationship
261-
return @errors.concat(Exceptions::FilterNotAllowed.new(filter_method).errors)
262-
end
266+
def parse_relationship_filter(key, value)
267+
included_resource_name, filter_method = key.to_s.split('.')
268+
filter_method = filter_method.to_sym if filter_method.present?
263269

264-
unless relationship.resource_klass._allowed_filter?(filter_method)
265-
return @errors.concat(Exceptions::FilterNotAllowed.new(filter_method).errors)
266-
end
270+
if included_resource_name
271+
relationship = resource_klass._relationship(included_resource_name || '')
267272

268-
unless @include_directives&.include_config(relationship.name.to_sym).present?
269-
return @errors.concat(Exceptions::FilterNotAllowed.new(filter_method).errors)
270-
end
273+
unless relationship
274+
return @errors.concat(Exceptions::FilterNotAllowed.new(filter_method).errors)
275+
end
271276

272-
verified_filter = relationship.resource_klass.verify_filters(filter_method => value)
273-
@include_directives.merge_filter(relationship.name, verified_filter)
274-
next
275-
else
276-
unless resource_klass._allowed_filter?(filter_method)
277-
return @errors.concat(Exceptions::FilterNotAllowed.new(filter_method).errors)
278-
end
277+
unless relationship.resource_klass._allowed_filter?(filter_method)
278+
return @errors.concat(Exceptions::FilterNotAllowed.new(filter_method).errors)
279+
end
279280

280-
@filters[filter_method] = value
281+
unless @include_directives.try(:include_config, relationship.name.to_sym).present?
282+
return @errors.concat(Exceptions::FilterNotAllowed.new(filter_method).errors)
281283
end
284+
285+
verified_filter = relationship.resource_klass.verify_filters(filter_method => value)
286+
@include_directives.merge_filter(relationship.name, verified_filter)
287+
else
288+
return @errors.concat(Exceptions::FilterNotAllowed.new(filter_method).errors)
282289
end
283290
end
284291

test/controllers/controller_test.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2644,6 +2644,22 @@ def test_show_with_filters_and_no_included_resources
26442644
end
26452645
end
26462646

2647+
class Api::V5::CollectorsControllerTest < ActionController::TestCase
2648+
def test_index_with_custom_filter_that_has_dot
2649+
get :index, params: {
2650+
filter: {
2651+
'name' => 'Alice',
2652+
'painting.title_equals': 'Helenka'
2653+
}
2654+
}
2655+
2656+
assert_response :success
2657+
assert_equal 1, json_response['data'].size
2658+
assert_equal '1', json_response['data'][0]['id']
2659+
refute json_response.key?('included')
2660+
end
2661+
end
2662+
26472663
class Api::V5::AuthorsControllerTest < ActionController::TestCase
26482664
def test_get_person_as_author
26492665
assert_cacheable_get :index, params: {filter: {id: '1'}}

test/fixtures/active_record.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,9 @@ class IsoCurrenciesController < JSONAPI::ResourceController
899899

900900
class PaintersController < JSONAPI::ResourceController
901901
end
902+
903+
class CollectorsController < JSONAPI::ResourceController
904+
end
902905
end
903906

904907
module V6
@@ -1671,6 +1674,11 @@ def collector_roster
16711674
class CollectorResource < JSONAPI::Resource
16721675
attributes :name
16731676
has_one :painting
1677+
1678+
filter :name
1679+
filter :'painting.title_equals', apply: -> (records, values, _opts) do
1680+
records.joins(:painting).where(paintings: { title: values })
1681+
end
16741682
end
16751683

16761684
class PainterResource < JSONAPI::Resource

test/test_helper.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,7 @@ class CatResource < JSONAPI::Resource
330330
jsonapi_resources :posts do
331331
end
332332
jsonapi_resources :painters
333+
jsonapi_resources :collectors
333334
jsonapi_resources :authors
334335
jsonapi_resources :expense_entries
335336
jsonapi_resources :iso_currencies

0 commit comments

Comments
 (0)