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 192 def accepts_grouped_inputs? false end
Convert a value into the expected type. If no value is given, fall back
to the default value.
@example
ActiveInteraction::Filter.new(:example).clean(nil, nil) # => ActiveInteraction::MissingValueError: example
@example
ActiveInteraction::Filter.new(:example).clean(0, nil) # => ActiveInteraction::InvalidValueError: example: 0
@example
ActiveInteraction::Filter.new(:example, default: nil).clean(nil, nil) # => nil
@example
ActiveInteraction::Filter.new(:example, default: 0).clean(nil, nil) # => ActiveInteraction::InvalidDefaultError: example: 0
@param value [Object] @param context [Base, nil]
@return [Object]
@raise [MissingValueError] If the value is missing and there is no
default.
@raise [InvalidValueError] If the value is invalid. @raise (see default
)
# File lib/active_interaction/filter.rb, line 101 def clean(value, context) value = cast(value, context) if value.nil? default(context) else value end 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 177 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 128 def default(context = nil) raise NoDefaultError, name unless default? value = raw_default(context) raise InvalidValueError if value.is_a?(GroupedInput) cast(value, context) rescue InvalidNestedValueError => e raise InvalidDefaultError, "#{name}: #{value.inspect} (#{e})" rescue InvalidValueError, MissingValueError raise InvalidDefaultError, "#{name}: #{value.inspect}" 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 162 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 148 def desc options[:desc] end
Private Instance Methods
# File lib/active_interaction/filter.rb, line 227 def adjust_output(value, _context) value end
rubocop:disable Metrics/MethodLength
# File lib/active_interaction/filter.rb, line 199 def cast(value, context, convert: true, reconstantize: true) if matches?(value) adjust_output(value, context) # we can't use `nil?` because BasicObject doesn't have it elsif value == nil # rubocop:disable Style/NilComparison raise MissingValueError, name unless default? nil elsif reconstantize send(__method__, value, context, convert: convert, reconstantize: false ) elsif convert send(__method__, convert(value), context, convert: false, reconstantize: reconstantize ) else raise InvalidValueError, "#{name}: #{describe(value)}" end end
# File lib/active_interaction/filter.rb, line 231 def convert(value) value end
# File lib/active_interaction/filter.rb, line 239 def describe(value) value.inspect rescue NoMethodError "(Object doesn't support #inspect)" end
# File lib/active_interaction/filter.rb, line 235 def klass @klass ||= Object.const_get(self.class.slug.to_s.camelize, false) end
rubocop:enable Metrics/MethodLength
# File lib/active_interaction/filter.rb, line 223 def matches?(_value) false end
# File lib/active_interaction/filter.rb, line 245 def raw_default(context) value = options.fetch(:default) return value unless value.is_a?(Proc) case value.arity when 1 then context.instance_exec(self, &value) else context.instance_exec(&value) end end