module Motor::ApiQuery::Filter

Constants

DISTINCT_RESTRICTED_COLUMN_TYPES
LIKE_FILTER_VALUE_REGEXP

Public Instance Methods

call(rel, params) click to toggle source
# File lib/motor/api_query/filter.rb, line 11
def call(rel, params)
  return rel if params.blank?

  normalized_params = normalize_params(Array.wrap(params))

  rel = rel.filter(normalized_params)
  rel = rel.distinct if can_apply_distinct?(rel)

  rel
end
can_apply_distinct?(rel) click to toggle source
# File lib/motor/api_query/filter.rb, line 54
def can_apply_distinct?(rel)
  rel.columns.none? do |column|
    DISTINCT_RESTRICTED_COLUMN_TYPES.include?(column.type)
  end
end
normalize_action(action, value) click to toggle source
# File lib/motor/api_query/filter.rb, line 60
def normalize_action(action, value)
  case action
  when 'includes'
    ['contains', value]
  when 'contains'
    ['ilike', value.sub(LIKE_FILTER_VALUE_REGEXP, '%\1%')]
  when 'starts_with'
    ['ilike', value.sub(LIKE_FILTER_VALUE_REGEXP, '\1%')]
  when 'ends_with'
    ['ilike', value.sub(LIKE_FILTER_VALUE_REGEXP, '%\1')]
  else
    [action, value]
  end
end
normalize_filter_hash(hash) click to toggle source
# File lib/motor/api_query/filter.rb, line 39
def normalize_filter_hash(hash)
  hash.each_with_object({}) do |(action, value), acc|
    new_action, new_value =
      if value.is_a?(Hash)
        [action, normalize_filter_hash(value)]
      else
        normalize_action(action, value)
      end

    acc[new_action] = new_value

    acc
  end
end
normalize_params(params) click to toggle source
# File lib/motor/api_query/filter.rb, line 22
def normalize_params(params)
  params.map do |item|
    next item if item.is_a?(String)
    next normalize_params(item) if item.is_a?(Array)

    item = item.to_unsafe_h if item.respond_to?(:to_unsafe_h)

    item.transform_values do |filter|
      if filter.is_a?(Hash)
        normalize_filter_hash(filter)
      else
        filter
      end
    end
  end.split('OR').product(['OR']).flatten(1)[0...-1]
end