Sha256: b72c5711687f8c934fcf978ee95e8a9b13fc6f03cf6340f7d1e18c2563343bdf

Contents?: true

Size: 1.92 KB

Versions: 60

Compression:

Stored size: 1.92 KB

Contents

# frozen_string_literal: true

module Motor
  module ApiQuery
    module Filter
      LIKE_FILTER_VALUE_REGEXP = /\A%?(.*?)%?\z/.freeze
      DISTINCT_RESTRICTED_COLUMN_TYPES = %i[json point].freeze

      module_function

      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

      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

      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

      def can_apply_distinct?(rel)
        rel.columns.none? do |column|
          DISTINCT_RESTRICTED_COLUMN_TYPES.include?(column.type)
        end
      end

      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
    end
  end
end

Version data entries

60 entries across 60 versions & 1 rubygems

Version Path
motor-admin-0.2.20 lib/motor/api_query/filter.rb
motor-admin-0.2.19 lib/motor/api_query/filter.rb
motor-admin-0.2.18 lib/motor/api_query/filter.rb
motor-admin-0.2.17 lib/motor/api_query/filter.rb
motor-admin-0.2.16 lib/motor/api_query/filter.rb
motor-admin-0.2.15 lib/motor/api_query/filter.rb
motor-admin-0.2.14 lib/motor/api_query/filter.rb
motor-admin-0.2.13 lib/motor/api_query/filter.rb
motor-admin-0.2.12 lib/motor/api_query/filter.rb
motor-admin-0.2.11 lib/motor/api_query/filter.rb
motor-admin-0.2.10 lib/motor/api_query/filter.rb
motor-admin-0.2.9 lib/motor/api_query/filter.rb
motor-admin-0.2.8 lib/motor/api_query/filter.rb
motor-admin-0.2.7 lib/motor/api_query/filter.rb
motor-admin-0.2.6 lib/motor/api_query/filter.rb
motor-admin-0.2.5 lib/motor/api_query/filter.rb
motor-admin-0.2.4 lib/motor/api_query/filter.rb
motor-admin-0.2.3 lib/motor/api_query/filter.rb
motor-admin-0.2.2 lib/motor/api_query/filter.rb
motor-admin-0.2.1 lib/motor/api_query/filter.rb