Class: RESTFramework::Filters::QueryFilter

Inherits:
BaseFilter
  • Object
show all
Defined in:
lib/rest_framework/filters/query_filter.rb

Overview

A simple filtering backend that supports filtering a recordset based on query parameters.

Constant Summary collapse

NIL_VALUES =
["nil", "null"].freeze

Instance Method Summary collapse

Methods inherited from BaseFilter

#initialize

Constructor Details

This class inherits a constructor from RESTFramework::Filters::BaseFilter

Instance Method Details

#_get_fieldsObject

Get a list of filter fields for the current action.



6
7
8
9
# File 'lib/rest_framework/filters/query_filter.rb', line 6

def _get_fields
  # Always return a list of strings; `@controller.get_fields` already does this.
  return @controller.class.filter_fields&.map(&:to_s) || @controller.get_fields
end

#_get_filter_paramsObject

Filter params for keys allowed by the current action’s filter_fields/fields config.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/rest_framework/filters/query_filter.rb', line 12

def _get_filter_params
  fields = self._get_fields
  includes = []

  filter_params = @controller.request.query_parameters.select { |p, _|
    # Remove any trailing `__in` from the field name.
    field = p.chomp("__in")

    # Remove any associations whose sub-fields are not filterable.
    if match = /(.*)\.(.*)/.match(field)
      field, sub_field = match[1..2]
      next false unless field.in?(fields)

      sub_fields = @controller.class.field_config_for(field)[:sub_fields] || []
      if sub_field.in?(sub_fields)
        includes << field.to_sym
        next true
      end

      next false
    end

    next field.in?(fields)
  }.map { |p, v|
    # Convert fields ending in `__in` to array values.
    if p.end_with?("__in")
      p = p.chomp("__in")
      v = v.split(",").map { |v| v.in?(NIL_VALUES) ? nil : v }
    end

    # Convert "nil" and "null" to nil.
    v = nil if v.in?(NIL_VALUES)

    [p, v]
  }.to_h.symbolize_keys

  return filter_params, includes
end

#filter_data(data) ⇒ Object

Filter data according to the request query parameters.



52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/rest_framework/filters/query_filter.rb', line 52

def filter_data(data)
  filter_params, includes = self._get_filter_params

  if filter_params.any?
    if includes.any?
      data = data.includes(*includes)
    end

    return data.where(**filter_params)
  end

  return data
end