module Filtered::Base::ClassMethods
Public Instance Methods
Defines a field in a filter.
When you provide no options, it will by default add a simple `where(year: [“2010”, “2011”])` clause to the query.
class CarFilter < ApplicationFilter field :year end
Or with a block which is passed with the current field value. Note that block must return proc which will be merged in the query:
class CarFilter < ApplicationFilter field :year do |value| -> { where(year: "20#{value}") } end end
The second argument to a block is filter object itself:
class CarFilter < ApplicationFilter attr_accessor :user field :year, allow_blank: true do |value, filter| -> { where(year: value, user: filter.user) } end end
Options:
-
:default
- Specifies a method (e.g.default: :default_year
), proc (e.g.default: Proc.new { |filter| filter.default_year }
) or object (e.gdefault: "2012"
) to call to determine default value. It will be called only if the field not passed into filter constructor. -
:allow_nil
- Add the field into query if field value isnil
. -
:allow_blank
- Add the field into query if the value is blank. -
:if
- Specifies a method or proc to call to determine if the field addition to query should occur (e.g.if: :allow_year
, orif: Proc.new { |year| %w(2018 2019).include?(year) }
). The method, or proc should return atrue
orfalse
value. -
:unless
- Specifies a method or proc to call to determine if the field addition to query should not occur (e.g.if: :allow_year
, orif: Proc.new { |year| (1999..2005).include?(year) }
). The method, or proc should return atrue
orfalse
value.
# File lib/filtered/base.rb, line 55 def field(field_name, options = {}, &block) field_name = field_name.to_sym field_definition = FieldDefinition.new.tap do |fd| fd.query_updater = if block_given? # TODO look for methods to validate that block returns proc block else # AR ref ->(value) { -> { where(field_name => value) } } end raise Error, "'if' can't be used with 'allow_nil' or 'allow_blank'" if options[:if] && (options[:allow_nil] || options[:allow_blank]) fd.acceptance_computer = if options[:if].is_a?(Proc) options[:if] elsif options[:if].is_a?(Symbol) -> (value, filter) { filter.send(options[:if], value) } elsif options[:if].nil? # TODO checking that value is blank just comparing to empty string is very naive ->(value) { (options[:allow_nil] || !value.nil?) && (options[:allow_blank] || value != "") } else raise Error, "Unsupported argument #{options[:if].class} for 'if'. Pass proc or method name" end raise Error, "'unless' can't be used with 'allow_nil' or 'allow_blank'" if options[:unless] && (options[:allow_nil] || options[:allow_blank]) fd.decline_computer = if options[:unless].is_a?(Proc) options[:unless] elsif options[:unless].is_a?(Symbol) -> (value, filter) { filter.send(options[:unless], value) } elsif options[:unless].nil? -> { false } else raise Error, "Unsupported argument #{options[:unless].class} for 'unless'. Pass proc or method name" end fd.default_computer = if options[:default].is_a?(Proc) options[:default] elsif options[:default].is_a?(Symbol) -> (filter) { filter.send(options[:default]) } elsif options[:default] -> (_) { options[:default] } end end field_definitions[field_name] = field_definition define_method field_name do fields[field_name] end end
# File lib/filtered/base.rb, line 111 def field_definitions instance_variable_get(:"@field_definitions") end