Skip to content

Instantly share code, notes, and snippets.

@8parth
Created December 17, 2018 02:57
Show Gist options
  • Save 8parth/26ddbc807a37ba349470b8e816c97502 to your computer and use it in GitHub Desktop.
Save 8parth/26ddbc807a37ba349470b8e816c97502 to your computer and use it in GitHub Desktop.
filterable concern
# frozen_string_literal: true
# Module maps filter parameters to filers
# class SomeClass < ApplicationRecord
# include Filterable
# ...
# scope :scope_name, ->(arg) { where(x: arg) }
# scope :another_scope, -> { where(b: :c) }
# available_filters param_key: { scope: :scope_name, args_needed: true }
# param_key2: { scope: another_scope }
# end
module Filterable
extend ActiveSupport::Concern
module ClassMethods
# cattr_accessor :filters
def available_filters(filters_array)
filters_hash = {}
filters_array.each do |filter, options|
mapped_scope = options[:scope].nil? ? filter : options[:scope]
args_needed = options[:args_needed].present? && options[:args_needed]
filters_hash[filter.to_sym] = { scope: mapped_scope, args_needed: args_needed } if singleton_methods.include?(mapped_scope)
end
instance_variable_set(:@filters, filters_hash.with_indifferent_access)
end
def filter(filtering_params)
results = where(nil)
filters = instance_variable_get(:@filters)
return results if filters.blank?
available_scopes = filter_keys
filtering_params.each do |key, value|
key = key.to_sym
next unless key.in?(available_scopes)
results =
if filters[key][:args_needed]
next if value.blank?
results.public_send(filters[key][:scope], value)
else
next unless ParseBoolean.from_str(value)
results.public_send(filters[key][:scope])
end
end
results
end
def filter_keys
instance_variable_get(:@filters)&.keys&.map(&:to_sym)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment