67 lines
1.7 KiB
Ruby
67 lines
1.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class Columns::LinkedDropDownColumn < Columns::ChampColumn
|
|
attr_reader :path
|
|
|
|
def initialize(procedure_id:, label:, stable_id:, tdc_type:, path:, options_for_select: [], displayable:, type: :text)
|
|
@path = path
|
|
|
|
super(
|
|
procedure_id:,
|
|
label:,
|
|
stable_id:,
|
|
tdc_type:,
|
|
displayable:,
|
|
type:,
|
|
options_for_select:
|
|
)
|
|
end
|
|
|
|
def filtered_ids(dossiers, search_terms)
|
|
relation = dossiers.with_type_de_champ(@stable_id)
|
|
|
|
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
|
|
|
|
private
|
|
|
|
def column_id = "type_de_champ/#{stable_id}->#{path}"
|
|
|
|
def typed_value(champ)
|
|
return nil if path == :value
|
|
|
|
primary_value, secondary_value = unpack_values(champ.value)
|
|
case path
|
|
when :primary
|
|
primary_value
|
|
when :secondary
|
|
secondary_value
|
|
end
|
|
end
|
|
|
|
def unpack_values(value)
|
|
JSON.parse(value)
|
|
rescue JSON::ParserError
|
|
[]
|
|
end
|
|
|
|
def safe_like(q) = ActiveRecord::Base.sanitize_sql_like(q)
|
|
end
|