Class: LcpRuby::DataSource::ApiFilterTranslator

Inherits:
Object
  • Object
show all
Defined in:
lib/lcp_ruby/data_source/api_filter_translator.rb

Overview

Translates Ransack-style filter params to a portable filter format that data source adapters can process.

Constant Summary collapse

PREDICATE_MAP =

Maps Ransack predicate suffixes to portable operator names

{
  "eq"      => "eq",
  "not_eq"  => "not_eq",
  "cont"    => "cont",
  "not_cont" => "not_cont",
  "lt"      => "lt",
  "lteq"    => "lteq",
  "gt"      => "gt",
  "gteq"    => "gteq",
  "in"      => "in",
  "null"    => "null",
  "not_null" => "not_null",
  "start"   => "start",
  "end"     => "end",
  "present" => "present",
  "blank"   => "blank",
  "true"    => "true",
  "false"   => "false"
}.freeze

Class Method Summary collapse

Class Method Details

.parse_ransack_key(key, field_names) ⇒ Array(String, String)?

Parse a Ransack key into [field_name, operator].

Parameters:

  • key (String)

    e.g. “name_cont”, “status_eq”

  • field_names (Array<String>)

    sorted by length desc

Returns:

  • (Array(String, String), nil)
    field_name, operator

    or nil



61
62
63
64
65
66
67
68
69
# File 'lib/lcp_ruby/data_source/api_filter_translator.rb', line 61

def self.parse_ransack_key(key, field_names)
  field_names.each do |field_name|
    next unless key.start_with?("#{field_name}_")
    suffix = key[(field_name.length + 1)..]
    operator = PREDICATE_MAP[suffix]
    return [ field_name, operator ] if operator
  end
  nil
end

.translate(ransack_params, field_names:, supported_operators: nil) ⇒ Array<Hash>

Translate Ransack-style params into portable filter array.

Parameters:

  • ransack_params (Hash)

    e.g. { “name_cont” => “tower”, “status_eq” => “active” }

  • field_names (Array<String>)

    known field names for this model

  • supported_operators (Array<String>) (defaults to: nil)

    operators the data source supports

Returns:

  • (Array<Hash>)

    e.g. [{ field: “name”, operator: “cont”, value: “tower” }]



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/lcp_ruby/data_source/api_filter_translator.rb', line 32

def self.translate(ransack_params, field_names:, supported_operators: nil)
  return [] if ransack_params.blank?

  # Sort field names longest first to match greedily
  sorted_fields = field_names.sort_by { |n| -n.length }

  filters = []
  ransack_params.each do |key, value|
    field, operator = parse_ransack_key(key.to_s, sorted_fields)
    next unless field && operator

    if supported_operators && !supported_operators.include?(operator)
      Rails.logger.warn(
        "[LcpRuby::ApiFilterTranslator] Dropping unsupported operator '#{operator}' " \
        "for field '#{field}' (supported: #{supported_operators.join(', ')})"
      )
      next
    end

    filters << { field: field, operator: operator, value: value }
  end

  filters
end