fix: filtering on linked_drop_down_column
This commit is contained in:
parent
09793420fb
commit
e94fd6db4c
2 changed files with 102 additions and 4 deletions
|
@ -17,10 +17,28 @@ class Columns::LinkedDropDownColumn < Columns::ChampColumn
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def filtered_ids(dossiers, values)
|
def filtered_ids(dossiers, search_terms)
|
||||||
dossiers.with_type_de_champ(@column)
|
relation = dossiers.with_type_de_champ(@stable_id)
|
||||||
.filter_ilike(:champs, :value, values)
|
|
||||||
.ids
|
case path
|
||||||
|
when :value
|
||||||
|
search_terms.flat_map do |search_term|
|
||||||
|
# when looking for "section 1 / option A",
|
||||||
|
# the value must contain both "section 1" and "option A"
|
||||||
|
primary, *secondary = search_term.split(%r{[[:space:]]*/[[:space:]]*})
|
||||||
|
safe_terms = [primary, *secondary].map { "%#{safe_like(_1)}%" }
|
||||||
|
|
||||||
|
relation.where("champs.value ILIKE ALL (ARRAY[?])", safe_terms).ids
|
||||||
|
end.uniq
|
||||||
|
when :primary
|
||||||
|
primary_terms = search_terms.map { |term| %{["#{safe_like(term)}","%"]} }
|
||||||
|
|
||||||
|
relation.where("champs.value ILIKE ANY (array[?])", primary_terms).ids
|
||||||
|
when :secondary
|
||||||
|
secondary_terms = search_terms.map { |term| %{["%","#{safe_like(term)}"]} }
|
||||||
|
|
||||||
|
relation.where("champs.value ILIKE ANY (array[?])", secondary_terms).ids
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -44,4 +62,6 @@ class Columns::LinkedDropDownColumn < Columns::ChampColumn
|
||||||
rescue JSON::ParserError
|
rescue JSON::ParserError
|
||||||
[]
|
[]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def safe_like(q) = ActiveRecord::Base.sanitize_sql_like(q)
|
||||||
end
|
end
|
||||||
|
|
78
spec/models/columns/linked_drop_down_column_spec.rb
Normal file
78
spec/models/columns/linked_drop_down_column_spec.rb
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
describe Columns::LinkedDropDownColumn do
|
||||||
|
describe '#filtered_ids' do
|
||||||
|
let(:procedure) { create(:procedure, types_de_champ_public: [{ type: :linked_drop_down_list, libelle: 'linked' }]) }
|
||||||
|
let(:type_de_champ) { procedure.active_revision.types_de_champ_public.first }
|
||||||
|
let(:kept_dossier) { create(:dossier, procedure: procedure) }
|
||||||
|
let(:discarded_dossier) { create(:dossier, procedure: procedure) }
|
||||||
|
|
||||||
|
subject { column.filtered_ids(Dossier.all, search_terms) }
|
||||||
|
|
||||||
|
context 'when path is :value' do
|
||||||
|
let(:column) { procedure.find_column(label: 'linked') }
|
||||||
|
|
||||||
|
before do
|
||||||
|
kept_dossier.champs.find_by(stable_id: type_de_champ.stable_id)
|
||||||
|
.update(value: %{["section 1","option A"]})
|
||||||
|
|
||||||
|
discarded_dossier.champs.find_by(stable_id: type_de_champ.stable_id)
|
||||||
|
.update(value: %{["section 1","option B"]})
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'when looking for a part' do
|
||||||
|
let(:search_terms) { ['option A'] }
|
||||||
|
|
||||||
|
it { is_expected.to eq([kept_dossier.id]) }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'when looking for the aggregated value' do
|
||||||
|
let(:search_terms) { ['section 1 / option A'] }
|
||||||
|
|
||||||
|
it { is_expected.to match_array([kept_dossier.id]) }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'when looking for the aggregated value or a common value' do
|
||||||
|
let(:search_terms) { ['section 1 / option A', 'section'] }
|
||||||
|
|
||||||
|
it { is_expected.to match_array([kept_dossier.id, discarded_dossier.id]) }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'when looking for a shared string' do
|
||||||
|
let(:search_terms) { ['option'] }
|
||||||
|
|
||||||
|
it { is_expected.to match_array([kept_dossier.id, discarded_dossier.id]) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when path is not :value' do
|
||||||
|
before do
|
||||||
|
kept_dossier.champs.find_by(stable_id: type_de_champ.stable_id)
|
||||||
|
.update(value: %{["1","2"]})
|
||||||
|
|
||||||
|
discarded_dossier.champs.find_by(stable_id: type_de_champ.stable_id)
|
||||||
|
.update(value: %{["2","1"]})
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when path is :primary' do
|
||||||
|
let(:column) { procedure.find_column(label: 'linked (Primaire)') }
|
||||||
|
|
||||||
|
describe 'when looking kept part' do
|
||||||
|
let(:search_terms) { ['1'] }
|
||||||
|
|
||||||
|
it { is_expected.to eq([kept_dossier.id]) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when path is :secondary' do
|
||||||
|
let(:column) { procedure.find_column(label: 'linked (Secondaire)') }
|
||||||
|
|
||||||
|
describe 'when looking kept part' do
|
||||||
|
let(:search_terms) { ['2'] }
|
||||||
|
|
||||||
|
it { is_expected.to eq([kept_dossier.id]) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue