class ActiveInteraction::Filter
Describes an input filter for an interaction.
Constants
- CLASSES
@return [Hash{Symbol => Class}]
Attributes
@return [Symbol]
@return [Hash{Symbol => Filter}]
@return [Symbol]
@return [Hash{Symbol => Object}]
Public Class Methods
Get the filter associated with a symbol.
@example
ActiveInteraction::Filter.factory(:boolean) # => ActiveInteraction::BooleanFilter
@example
ActiveInteraction::Filter.factory(:invalid) # => ActiveInteraction::MissingFilterError: :invalid
@param slug [Symbol]
@return [Class]
@raise [MissingFilterError] If the slug doesn’t map to a filter.
@see .slug
# File lib/active_interaction/filter.rb, line 50 def factory(slug) CLASSES.fetch(slug) { raise MissingFilterError, slug.inspect } end
@param name [Symbol] @param options [Hash{Symbol => Object}]
@option options [Object] :default Fallback value to use when given ‘nil`.
# File lib/active_interaction/filter.rb, line 68 def initialize(name, options = {}, &block) @name = name @options = options.dup @filters = {} instance_eval(&block) if block_given? end
Private Class Methods
@param slug [Symbol]
@return [Class]
# File lib/active_interaction/filter.rb, line 59 def register(slug) CLASSES[@slug = slug] = self end
Public Instance Methods
Tells whether or not the filter accepts a group of parameters to form a single input.
@example
ActiveInteraction::TimeFilter.new(Time.now).accepts_grouped_inputs? # => true
@example
ActiveInteraction::Filter.new(:example).accepts_grouped_inputs? # => false
@return [Boolean]
# File lib/active_interaction/filter.rb, line 183 def accepts_grouped_inputs? false end
Gets the type of database column that would represent the filter data.
@example
ActiveInteraction::TimeFilter.new(Time.now).database_column_type # => :datetime
@example
ActiveInteraction::Filter.new(:example).database_column_type # => :string
@return [Symbol] A database column type. If no sensible mapping exists,
returns `:string`.
# File lib/active_interaction/filter.rb, line 168 def database_column_type :string end
Get the default value.
@example
ActiveInteraction::Filter.new(:example).default # => ActiveInteraction::NoDefaultError: example
@example
ActiveInteraction::Filter.new(:example, default: nil).default # => nil
@example
ActiveInteraction::Filter.new(:example, default: 0).default # => ActiveInteraction::InvalidDefaultError: example: 0
@param context [Base, nil]
@return [Object]
@raise [NoDefaultError] If the default is missing. @raise [InvalidDefaultError] If the default is invalid.
# File lib/active_interaction/filter.rb, line 114 def default(context = nil) raise NoDefaultError, name unless default? value = raw_default(context) raise InvalidDefaultError, "#{name}: #{value.inspect}" if value.is_a?(GroupedInput) if value.nil? nil else default = process(value, context) if default.errors.any? && default.errors.first.is_a?(Filter::Error) raise InvalidDefaultError, "#{name}: #{value.inspect}" end default.value end end
Tells if this filter has a default value.
@example
ActiveInteraction::Filter.new(:example).default? # => false
@example
ActiveInteraction::Filter.new(:example, default: nil).default? # => true
@return [Boolean]
# File lib/active_interaction/filter.rb, line 153 def default? options.key?(:default) end
Get the description.
@example
ActiveInteraction::Filter.new(:example, desc: 'Description!').desc # => "Description!"
@return [String, nil]
# File lib/active_interaction/filter.rb, line 139 def desc options[:desc] end
Processes the input through the filter and returns a variety of data
about the input.
@example
input = ActiveInteraction::Filter.new(:example, default: nil).process(nil, nil) input.value # => nil
@param value [Object] @param context [Base, nil]
@return [Input, ArrayInput
, HashInput]
@raise (see default
)
# File lib/active_interaction/filter.rb, line 90 def process(value, context) value, error = cast(value, context) Input.new(self, value: value, error: error) end
Private Instance Methods
# File lib/active_interaction/filter.rb, line 214 def adjust_output(value, _context) value end
rubocop:disable Metrics/PerceivedComplexity
# File lib/active_interaction/filter.rb, line 190 def cast(value, context, convertize: true, reconstantize: true) if matches?(value) [adjust_output(value, context), nil] elsif value == nil # rubocop:disable Style/NilComparison - BasicObject does not have `nil?` default? ? [default(context), nil] : [value, Filter::Error.new(self, :missing)] elsif reconstantize send(__method__, value, context, convertize: convertize, reconstantize: false) elsif convertize value, error = convert(value) if error [value, error] else send(__method__, value, context, convertize: false, reconstantize: reconstantize) end else [value, Filter::Error.new(self, :invalid_type)] end end
# File lib/active_interaction/filter.rb, line 218 def convert(value) [value, nil] end
# File lib/active_interaction/filter.rb, line 226 def describe(value) value.inspect rescue NoMethodError "(Object doesn't support #inspect)" end
# File lib/active_interaction/filter.rb, line 222 def klass @klass ||= Object.const_get(self.class.slug.to_s.camelize, false) end
rubocop:enable Metrics/PerceivedComplexity
# File lib/active_interaction/filter.rb, line 210 def matches?(_value) false end
# File lib/active_interaction/filter.rb, line 232 def raw_default(context) value = options.fetch(:default) return value unless value.is_a?(Proc) if value.arity == 1 context.instance_exec(self, &value) else context.instance_exec(&value) end end