class Filtered::Base

Public Class Methods

inherited(base) click to toggle source
Calls superclass method
# File lib/filtered/base.rb, line 133
def self.inherited(base)
  base.instance_variable_set(:"@field_definitions", Hash.new)

  if field_definitions
    field_definitions.each do |(name, definition)|
      base.field_definitions[name] = definition
    end
  end

  super
end
new(params = {}) { |self| ... } click to toggle source

Initializes a new filter with the given params.

 class CarFilter < ApplicationFilter

   attr_accessor :user

   field :year, allow_blank: true do |value, filter|
     -> { where(year: value, user: filter.user) }
   end

   field :make
   field :model
   field :body

 end

 class NoiseMeasurementsController < ApplicationController
   before_action :set_filter

   def index
     @measurements = CarNoiseMeasurement.all.merge(@filter)
   end

   private

   def set_filter
     @filter = CarsFilter.new(filter_params) do |f|
      f.user = current_user
     end
   end

   def filter_params
     params.fetch(:filter, {}).permit(make: [], model: [], year: [], body: [])
   end
end
# File lib/filtered/base.rb, line 181
def initialize(params = {}, &block)
  params.each do |name, value|
    name = name.to_sym

    raise Error, "Passing '#{name}' filter which is not defined" unless fields.defined?(name)

    fields[name] = value
  end

  yield self if block_given?

  fields.each do |name, value, definition|
    next if value || !definition.default_computer

    fields[name] = definition.default_computer.(self)
  end
end

Public Instance Methods

inspect() click to toggle source
# File lib/filtered/base.rb, line 218
def inspect
  inspection = entitled_fields.collect { |name, value| "#{name}: #{value.inspect}" }.compact.join(", ")

  "#<#{self.class} #{inspection}>"
end
to_hash() click to toggle source
# File lib/filtered/base.rb, line 214
def to_hash
  Hash[entitled_fields.map { |name, value| [name, value] }]
end
to_proc() click to toggle source

ActiveRecord calls to_proc when filter merged into relation.

# File lib/filtered/base.rb, line 201
def to_proc
  procs = entitled_fields.inject([]) do |memo, (name, value, definition)|
    memo << eval_option_proc(definition.query_updater, value)

    memo
  end

  ->() {
    # here self is an ActiveRecord relation
    procs.inject(self) { |chain, next_proc| chain.merge(next_proc) }
  }
end

Private Instance Methods

entitled_fields() { |name, value, definition| ... } click to toggle source
# File lib/filtered/base.rb, line 226
def entitled_fields
  return enum_for(:entitled_fields) unless block_given?

  fields.each do |name, value, definition|
    value_accepted = eval_option_proc(definition.acceptance_computer, value)
    value_declined = eval_option_proc(definition.decline_computer, value)

    if value_accepted && !value_declined
      yield name, value, definition
    else
      next
    end
  end
end
eval_option_proc(proc_, value) click to toggle source
# File lib/filtered/base.rb, line 241
def eval_option_proc(proc_, value)
  if proc_.arity == 2
    proc_.call(value, self)
  elsif proc_.arity == 1
    proc_.call(value)
  elsif proc_.arity == 0
    proc_.call()
  else
    raise Error, "Unsupported number of arguments for proc"
  end
end