class Filterer::Base
Attributes
meta[RW]
opts[RW]
params[RW]
results[RW]
sort[RW]
Public Class Methods
chain(params = {}, opts = {})
click to toggle source
@return [ActiveRecord::Association]
# File lib/filterer/base.rb, line 65 def chain(params = {}, opts = {}) new(params, opts.merge( skip_ordering: true, skip_pagination: true )).results end
filter(params = {}, opts = {})
click to toggle source
Public API @return [ActiveRecord::Association]
# File lib/filterer/base.rb, line 53 def filter(params = {}, opts = {}) new(params, opts).results end
filter_without_pagination(params = {}, opts = {})
click to toggle source
@return [ActiveRecord::Association]
# File lib/filterer/base.rb, line 58 def filter_without_pagination(params = {}, opts = {}) new(params, opts.merge( skip_pagination: true )).results end
new(params = {}, opts = {})
click to toggle source
# File lib/filterer/base.rb, line 73 def initialize(params = {}, opts = {}) self.opts = opts self.params = defaults.merge(parse_strong_parameters(params)). with_indifferent_access self.results = opts[:starting_query] || starting_query self.results = apply_default_filters || results add_params_to_query self.results = ordered_results unless opts[:skip_ordering] paginate_results unless opts[:skip_pagination] extend_active_record_relation end
sort_option(key, string_or_proc = nil, opts = {})
click to toggle source
Macro for adding sort options
# File lib/filterer/base.rb, line 23 def sort_option(key, string_or_proc = nil, opts = {}) if string_or_proc.is_a?(Hash) opts, string_or_proc = string_or_proc.clone, nil end if !string_or_proc if key.is_a?(String) string_or_proc = key else raise 'Please provide a query string or a proc.' end end if key.is_a?(Regexp) && opts[:default] raise "Default sort option can't have a Regexp key." end if string_or_proc.is_a?(Proc) && opts[:tiebreaker] raise "Tiebreaker can't be a proc." end self.sort_options += [{ key: key, string_or_proc: string_or_proc, opts: opts }] end
Public Instance Methods
defaults()
click to toggle source
# File lib/filterer/base.rb, line 85 def defaults {} end
direction()
click to toggle source
# File lib/filterer/base.rb, line 93 def direction params[:direction].try(:downcase) == 'desc' ? 'desc' : 'asc' end
starting_query()
click to toggle source
# File lib/filterer/base.rb, line 89 def starting_query raise 'You must override this method!' end
Private Instance Methods
add_params_to_query()
click to toggle source
# File lib/filterer/base.rb, line 136 def add_params_to_query present_params.each do |k, v| method_name = "param_#{k}" if respond_to?(method_name) self.results = send(method_name, v) || results end end end
apply_default_filters()
click to toggle source
# File lib/filterer/base.rb, line 132 def apply_default_filters results end
current_page()
click to toggle source
# File lib/filterer/base.rb, line 170 def current_page [params[:page].to_i, 1].max end
default_sort_option()
click to toggle source
# File lib/filterer/base.rb, line 215 def default_sort_option self.class.sort_options.detect do |sort_option| sort_option[:opts][:default] end || filterer_default_sort_option end
extend_active_record_relation()
click to toggle source
# File lib/filterer/base.rb, line 235 def extend_active_record_relation results.instance_variable_set(:@filterer, self) results.extending! do def filterer @filterer end end end
filterer()
click to toggle source
# File lib/filterer/base.rb, line 239 def filterer @filterer end
filterer_default_sort_option()
click to toggle source
# File lib/filterer/base.rb, line 221 def filterer_default_sort_option { key: 'default', string_or_proc: "#{results.model.table_name}.id", opts: {} } end
find_sort_option_from_param(x)
click to toggle source
@param x [String] @return [Hash] sort_option
# File lib/filterer/base.rb, line 180 def find_sort_option_from_param(x) self.class.sort_options.detect do |sort_option| if sort_option[:key].is_a?(Regexp) x.match(sort_option[:key]) else # String x == sort_option[:key] end end end
order_by_sort_option(opt)
click to toggle source
# File lib/filterer/base.rb, line 200 def order_by_sort_option(opt) results.order %{ #{opt[:string_or_proc]} #{direction} #{opt[:opts][:nulls_last] ? 'NULLS LAST' : ''} #{tiebreaker_sort_string ? ', ' + tiebreaker_sort_string : ''} }.squish end
order_by_sort_proc()
click to toggle source
# File lib/filterer/base.rb, line 190 def order_by_sort_proc if (sort_string = sort_proc_to_string(sort_option)) order_by_sort_option(sort_option.merge( string_or_proc: sort_string )) else order_by_sort_option(filterer_default_sort_option) end end
ordered_results()
click to toggle source
# File lib/filterer/base.rb, line 152 def ordered_results if sort_option && sort_option[:string_or_proc].is_a?(String) order_by_sort_option(sort_option) elsif sort_option && sort_option[:string_or_proc].is_a?(Proc) order_by_sort_proc else order_by_sort_option(default_sort_option) end end
paginate_results()
click to toggle source
# File lib/filterer/base.rb, line 110 def paginate_results if per_page && paginator send("paginate_results_with_#{paginator}") end end
paginate_results_with_kaminari()
click to toggle source
# File lib/filterer/base.rb, line 124 def paginate_results_with_kaminari self.results = results.page(current_page).per(per_page) end
paginate_results_with_will_paginate()
click to toggle source
# File lib/filterer/base.rb, line 128 def paginate_results_with_will_paginate self.results = results.paginate(page: current_page, per_page: per_page) end
paginator()
click to toggle source
# File lib/filterer/base.rb, line 116 def paginator if defined?(Kaminari) :kaminari elsif defined?(WillPaginate) :will_paginate end end
parse_strong_parameters(params)
click to toggle source
# File lib/filterer/base.rb, line 245 def parse_strong_parameters(params) params.try(:to_unsafe_h) || params end
per_page()
click to toggle source
# File lib/filterer/base.rb, line 162 def per_page if self.class.allow_per_page_override && params[:per_page].present? [params[:per_page].to_i, per_page_max].min else self.class.per_page end end
present_params()
click to toggle source
# File lib/filterer/base.rb, line 146 def present_params params.select do |_k, v| v.present? end end
sort_option()
click to toggle source
# File lib/filterer/base.rb, line 174 def sort_option @sort_option ||= find_sort_option_from_param(sort) end
sort_proc_to_string(opt)
click to toggle source
# File lib/filterer/base.rb, line 209 def sort_proc_to_string(opt) sort_key = opt[:key] matches = sort_key.is_a?(Regexp) && params[:sort].match(sort_key) instance_exec matches, &opt[:string_or_proc] end
tiebreaker_sort_string()
click to toggle source
# File lib/filterer/base.rb, line 229 def tiebreaker_sort_string self.class.sort_options.detect do |sort_option| sort_option[:opts][:tiebreaker] end.try(:[], :string_or_proc) end