Module: Motor::ApiQuery::Filter
- Defined in:
- lib/motor/api_query/filter.rb
Constant Summary collapse
- LIKE_FILTER_VALUE_REGEXP =
/\A%?(.*?)%?\z/.freeze
- DISTINCT_RESTRICTED_COLUMN_TYPES =
%i[json point].freeze
Class Method Summary collapse
- .call(rel, params) ⇒ Object
- .can_apply_distinct?(rel) ⇒ Boolean
- .normalize_action(action, value) ⇒ Object
- .normalize_filter_hash(hash) ⇒ Object
- .normalize_params(params) ⇒ Object
Class Method Details
.call(rel, params) ⇒ Object
11 12 13 14 15 16 17 18 19 20 |
# 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) ⇒ Boolean
54 55 56 57 58 |
# 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) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# 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')] when 'eqnull' ['eq', nil] when 'neqnull' ['neq', nil] else [action, value] end end |
.normalize_filter_hash(hash) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# 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) ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# 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 |