Skip to content

Commit 801f5d1

Browse files
authored
fix(filters): properly parse filters from request params (#743)
1 parent 6fa08a6 commit 801f5d1

File tree

2 files changed

+78
-7
lines changed

2 files changed

+78
-7
lines changed

app/services/forest_liana/resources_getter.rb

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,15 +198,29 @@ def field_names_requested
198198

199199
def extract_associations_from_filter
200200
associations = []
201-
@params[:filter]&.each do |field, _|
202-
if field.include?(':')
201+
202+
filters = @params[:filters]
203+
filters = JSON.parse(filters) if filters.is_a?(String)
204+
205+
conditions = []
206+
207+
if filters.is_a?(Hash) && filters.key?('conditions')
208+
conditions = filters['conditions']
209+
elsif filters.is_a?(Hash) && filters.key?('field')
210+
conditions = [filters]
211+
end
212+
213+
conditions.each do |condition|
214+
field = condition['field']
215+
if field&.include?(':')
203216
associations << field.split(':').first.to_sym
204217
@count_needs_includes = true
205218
end
206219
end
220+
207221
@count_needs_includes = true if @params[:search]
208222

209-
associations
223+
associations.uniq
210224
end
211225

212226
def prepare_query

spec/services/forest_liana/resources_getter_spec.rb

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ def association_connection.current_database
309309
describe 'when filtering on an ambiguous field' do
310310
let(:resource) { Tree }
311311
let(:pageSize) { 5 }
312-
let(:fields) { { 'Tree' => 'id' } }
312+
let(:fields) { { 'Tree' => 'id,name', 'cutter' => 'id' } }
313313
let(:filters) { {
314314
aggregator: 'and',
315315
conditions: [{
@@ -332,7 +332,6 @@ def association_connection.current_database
332332
expect(count).to eq 1
333333
expect(records.first.id).to eq 3
334334
expect(records.first.name).to eq 'Apple Tree'
335-
expect(records.first.cutter.name).to eq 'Michel'
336335
end
337336
end
338337

@@ -379,7 +378,7 @@ def association_connection.current_database
379378
describe 'when sorting on an ambiguous field name with a filter' do
380379
let(:resource) { Tree }
381380
let(:sort) { '-name' }
382-
let(:fields) { { 'Tree' => 'id' } }
381+
let(:fields) { { 'Tree' => 'id,name' } }
383382
let(:filters) { {
384383
field: 'cutter:name',
385384
operator: 'equal',
@@ -417,7 +416,7 @@ def association_connection.current_database
417416

418417
describe 'when filtering on an updated_at field of an associated collection' do
419418
let(:resource) { Tree }
420-
let(:fields) { { 'Tree' => 'id' } }
419+
let(:fields) { { 'Tree' => 'id,name' } }
421420
let(:filters) { {
422421
field: 'island:updated_at',
423422
operator: 'previous_year'
@@ -592,6 +591,64 @@ def association_connection.current_database
592591
end
593592
end
594593

594+
describe '#extract_associations_from_filter' do
595+
let(:resource) { Tree }
596+
597+
before { init_scopes }
598+
599+
context 'with a single filter as JSON string' do
600+
let(:filters) {
601+
{
602+
field: 'island:updated_at',
603+
operator: 'equal',
604+
value: '2024-01-01'
605+
}.to_json
606+
}
607+
608+
it 'extracts the correct association' do
609+
expect(getter.send(:extract_associations_from_filter)).to eq [:island]
610+
end
611+
end
612+
613+
context 'with grouped conditions as JSON string' do
614+
let(:filters) {
615+
{
616+
aggregator: 'and',
617+
conditions: [
618+
{ field: 'island:updated_at', operator: 'equal', value: '2024-01-01' },
619+
{ field: 'owner:name', operator: 'equal', value: 'Michel' },
620+
{ field: 'id', operator: 'present', value: nil }
621+
]
622+
}.to_json
623+
}
624+
625+
it 'extracts all unique associations' do
626+
expect(getter.send(:extract_associations_from_filter)).to match_array [:island, :owner]
627+
end
628+
end
629+
630+
context 'when filters has no association field' do
631+
let(:filters) {
632+
{
633+
field: 'id',
634+
operator: 'equal',
635+
value: 1
636+
}.to_json
637+
}
638+
639+
it 'returns an empty array' do
640+
expect(getter.send(:extract_associations_from_filter)).to eq []
641+
end
642+
end
643+
644+
context 'when filters is nil' do
645+
let(:filters) { nil }
646+
647+
it 'returns an empty array' do
648+
expect(getter.send(:extract_associations_from_filter)).to eq []
649+
end
650+
end
651+
end
595652
end
596653
end
597654
end

0 commit comments

Comments
 (0)