class Right::FilterParametersExtractor

User provided filters syntax:

* `{ 'name_eq' => 'Martin' }` - name is equal to Martin
* `{ 'name_in' => 'Martin,Bob' }` - name is either Martin or Bob

This middleware parses filters hash and builds Parameter array @see Right::FilterParameter

If user passes not defined filter, it yields to `UndefinedParameter`, so you may validate it.

Attributes

app[R]
parameters_definition[R]

Public Class Methods

new(app, parameters_definition) click to toggle source

@param app [#call] @param parameters_definition [Set<Right::FilterParameterDefinition>]

# File lib/right/filter_parameters_extractor.rb, line 16
def initialize(app, parameters_definition)
  @app = app
  @parameters_definition = parameters_definition
end

Public Instance Methods

call(env) click to toggle source

@param env [<{:filter => Hash}, []>]

* first element is a scope to be filtered
* second is a hash with user provided filters

@return [<{:filter => <Right::FilterParameter>, []}]

# File lib/right/filter_parameters_extractor.rb, line 26
def call(env)
  params, errors = env

  provided_parameters = Hash(params[:filter]).each_with_object(FilterParameters.new) do |(name, value), parameters|
    type_casted_value = type_cast_value(name, value)
    parameters << extract_parameter(name, type_casted_value)
  end

  not_provided_parameters = parameters_definition - provided_parameters.map(&:definition)

  undefined_parameters = not_provided_parameters.map do |definition|
    FilterParameter.new(nil, nil, definition)
  end

  # Keep even undefined parameters to validate required ones
  filters = provided_parameters + undefined_parameters

  app.call([params.merge(filter: filters), errors])
end

Private Instance Methods

extract_parameter(name, value) click to toggle source

@param [String] name @param [String, Array<String>] value

# File lib/right/filter_parameters_extractor.rb, line 61
def extract_parameter(name, value)
  name, predicate = name_and_predicate(name)
  definition = parameters_definition.detect { |d| d.as == name } || FilterUndefinedParameter.new(name)
  FilterParameter.new(value, predicate, definition)
end
name_and_predicate(name_with_predicate) click to toggle source
# File lib/right/filter_parameters_extractor.rb, line 50
def name_and_predicate(name_with_predicate)
  predicate = FilterPredicates.all.detect { |p| name_with_predicate.end_with?("_#{p}") }
  [
    name_with_predicate.chomp("_#{predicate}"),
    predicate,
  ]
end
type_cast_value(name, value) click to toggle source
# File lib/right/filter_parameters_extractor.rb, line 67
def type_cast_value(name, value)
  if name.end_with?(*FilterPredicates.array)
    value.split(',')
  else
    value
  end
end