Class: EasyFilters::ModelFilter
- Defined in:
- lib/easy_filters/model_filter.rb
Overview
Base class for ActiveRecord-bound filter classes. Subclasses must implement the #model method and optionally add custom filtering methods, as explained below in the #apply_to method.
Instance Method Summary collapse
-
#all ⇒ Object
Get all the matching records to the current filter criteria.
-
#apply_to(matches) ⇒ Object
Applies the filter criteria specified for the different fields to :matches, an ActiveRecordRelation which should start by matching all the “filterable” records.
-
#filter_string_field(partial, field, value) ⇒ Object
Filters String fields using LIKE.
-
#model ⇒ Object
Get the model class to which the filters will be applied.
-
#scope ⇒ Object
Get the scope that will start the filter criteria as a symbol.
Methods inherited from Filter
#[], #[]=, #any?, #clear!, defaults, global_key, #initialize, #key, key, #persist!, #sanitize, #values, #values=
Constructor Details
This class inherits a constructor from EasyFilters::Filter
Instance Method Details
#all ⇒ Object
Get all the matching records to the current filter criteria.
13 14 15 16 |
# File 'lib/easy_filters/model_filter.rb', line 13 def all matches = model.send(scope) matches = apply_to matches end |
#apply_to(matches) ⇒ Object
Applies the filter criteria specified for the different fields to :matches, an ActiveRecordRelation which should start by matching all the “filterable” records.
Each field will be processed in the following way:
-
Check if self responds to a custom filter method of the form: “filter_by_<FIELD_NAME>”. If it does, delegate the filtering of records by that field to the method. Such a method must return the updated ActiveRecordRelation. For instance, if the field name is “slug”, its custom filter method will be named “filter_by_slug”:
def filter_by_slug(partial, value) partial.where(slug: value) end
-
If no custom filter method is available for the field, check for a default filter method by the class of the value. Supported classes out-of-the-box are:
-
String: Will search with a ‘like “%value%”’.
-
-
Otherwise, leave the logic up to ActiveRecord. Will add a where constraint like follows:
partial.where(field.to_sym => value)
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/easy_filters/model_filter.rb', line 47 def apply_to(matches) values.inject(matches) do |partial, pair| field, value = pair unless value.blank? type = value.class.name.downcase custom_filter_method = "filter_by_#{field}" default_filter_method = "filter_#{type}_field" if self.respond_to? custom_filter_method # Custom filtering partial = self.send custom_filter_method, partial, value elsif self.respond_to? default_filter_method # Default method filtering partial = self.send default_filter_method, partial, field, value else # Leave it up to AR and its magic partial = partial.where(field.to_sym => value) end end partial end end |
#filter_string_field(partial, field, value) ⇒ Object
Filters String fields using LIKE.
71 72 73 |
# File 'lib/easy_filters/model_filter.rb', line 71 def filter_string_field(partial, field, value) partial.where("#{field} like ?", "%#{value}%") end |
#model ⇒ Object
Get the model class to which the filters will be applied. This method must be overridden in subclasses.
8 9 10 |
# File 'lib/easy_filters/model_filter.rb', line 8 def model raise NotImplementedError end |
#scope ⇒ Object
Get the scope that will start the filter criteria as a symbol. The default scope is :all.
20 21 22 |
# File 'lib/easy_filters/model_filter.rb', line 20 def scope :all end |