53 lines
1.7 KiB
Ruby
53 lines
1.7 KiB
Ruby
|
class Columns::JSONPathColumn < Column
|
|||
|
def column
|
|||
|
"#{@column}->#{value_column}" # override column otherwise json path facets will have same id as other
|
|||
|
end
|
|||
|
|
|||
|
def filtered_ids(dossiers, search_occurences)
|
|||
|
queries = Array.new(search_occurences.count, "(#{json_path_query_part} ILIKE ?)").join(' OR ')
|
|||
|
dossiers.with_type_de_champ(stable_id)
|
|||
|
.where(queries, *(search_occurences.map { |value| "%#{value}%" }))
|
|||
|
.ids
|
|||
|
end
|
|||
|
|
|||
|
def options_for_select
|
|||
|
case value_column.last
|
|||
|
when 'departement_code'
|
|||
|
APIGeoService.departements.map { ["#{_1[:code]} – #{_1[:name]}", _1[:code]] }
|
|||
|
when 'region_name'
|
|||
|
APIGeoService.regions.map { [_1[:name], _1[:name]] }
|
|||
|
else
|
|||
|
[]
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
private
|
|||
|
|
|||
|
def stable_id
|
|||
|
@column
|
|||
|
end
|
|||
|
|
|||
|
# given a value_column as ['value_json', 'address', 'postal_code']
|
|||
|
# build SQL query as 'champs'.'value_json'->'address'->>'postal_code'
|
|||
|
# see: https://www.postgresql.org/docs/9.5/functions-json.html
|
|||
|
def json_path_query_part
|
|||
|
*json_segments, key = value_column
|
|||
|
|
|||
|
if json_segments.blank? # not nested, only access using ->> Get JSON array element as text
|
|||
|
"#{quote_table_column('champs')}.#{quote_table_column('value_json')}->>#{quote_json_segment(key)}"
|
|||
|
else # nested, have to dig in json using -> Get JSON object field by key
|
|||
|
field_accessor = json_segments.map(&method(:quote_json_segment)).join('->')
|
|||
|
|
|||
|
"#{quote_table_column('champs')}.#{quote_table_column('value_json')}->#{field_accessor}->>#{quote_json_segment(key)}"
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
def quote_table_column(table_or_column)
|
|||
|
ActiveRecord::Base.connection.quote_column_name(table_or_column)
|
|||
|
end
|
|||
|
|
|||
|
def quote_json_segment(path)
|
|||
|
"'#{path}'"
|
|||
|
end
|
|||
|
end
|