Class: LcpRuby::Search::CustomFieldFilter

Inherits:
Object
  • Object
show all
Defined in:
lib/lcp_ruby/search/custom_field_filter.rb

Constant Summary collapse

VALID_OPERATORS =
OperatorRegistry::ALL_OPERATORS
CAST_MAP =
{
  "integer" => :integer,
  "float" => :decimal,
  "decimal" => :decimal,
  "date" => :date,
  "datetime" => :date
}.freeze

Class Method Summary collapse

Class Method Details

.apply(scope, table_name, field_name, operator, value, cast: nil) ⇒ ActiveRecord::Relation

Apply a single custom field condition to a scope.

Parameters:

  • scope (ActiveRecord::Relation)
  • table_name (String)
  • field_name (String)

    custom field name (validated)

  • operator (Symbol)

    one of VALID_OPERATORS

  • value (String, Array)

    the filter value

  • cast (Symbol, nil) (defaults to: nil)

    type cast (:integer, :decimal, :date)

Returns:

  • (ActiveRecord::Relation)


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/lcp_ruby/search/custom_field_filter.rb', line 24

def apply(scope, table_name, field_name, operator, value, cast: nil)
  CustomFields::Query.validate_field_name!(field_name)
  operator = operator.to_sym

  unless VALID_OPERATORS.include?(operator)
    Rails.logger.warn(
      "[LcpRuby::CustomFieldFilter] Unknown operator: #{operator.inspect} for field #{field_name}"
    )
    return scope
  end

  expr = json_extract_expr(table_name, field_name)
  cast_expr = cast ? apply_cast(expr, cast) : expr

  condition = build_condition(cast_expr, expr, operator, value)
  return scope unless condition

  scope.where(Arel.sql(condition))
end

.cast_for_type(custom_type) ⇒ Object

Determine the cast type for a custom field type.



45
46
47
# File 'lib/lcp_ruby/search/custom_field_filter.rb', line 45

def cast_for_type(custom_type)
  CAST_MAP[custom_type.to_s]
end

.parse_cf_key(key, sorted_field_names) ⇒ Array(String, String)?

Parse a composite cf key into [field_name, operator]. Keys arrive as “field_name_operator” (e.g., “priority_eq”).

Parameters:

  • key (String)

    the composite key

  • sorted_field_names (Array<String>)

    field names sorted by length desc

Returns:

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

    or nil



54
55
56
57
58
59
60
61
62
63
64
# File 'lib/lcp_ruby/search/custom_field_filter.rb', line 54

def parse_cf_key(key, sorted_field_names)
  key = key.to_s
  sorted_field_names.each do |name|
    prefix = "#{name}_"
    if key.start_with?(prefix)
      operator = key[prefix.length..]
      return [ name, operator ] if operator.present?
    end
  end
  nil
end