EasyFilters

This gem provides a simple API for defining dynamic persistent(in session) filters based on active record models.

Installation

Add this line to your application's Gemfile:


    gem 'easy_filters'

And then execute:


    $ bundle

Usage

EasyFilters expects you to define the following methods:

class ArticlesFilter < EasyFilters::ModelFilter

  # Default values for this filter.
  def self.defaults
    { body: nil, date_from: nil, date_to: nil }
  end

  # Model class to be filtered.
  def model
    Article
  end
end

  • defaults: defines the fields that will be used for filtering and its defaults values
  • model: returns the target class to be filtered

Customizing filtering strategy

For defining the parts of the query that will filter each each field, define a method named filter_by_#{field_name}. The field must be present in the defaults array.

Each filter_by_* method receives 2 params:

  • scope: The actual query.
  • value: The value for the current field

For example:

class ArticlesFilter < ModelFilter

  #(...) previously defined methods

  # Custom filter method for :body field.
  def filter_by_body(scope, value)
    matcher = "%#{value}%"
    scope.where('body like ? OR body like ?', matcher, matcher)
  end

  # The following 2 filter_by builds an from/to/between date filter:

  # Custom filter method for :date_from field.
  def filter_by_date_from(scope, value)
    scope.joins(:editions).where('editions.date >= ?', Date.parse(value))
  end

  # Custom filter method for :date_to field.
  def filter_by_date_to(scope, value)
    scope.joins(:editions).where('editions.date <= ?', Date.parse(value))
  end
end

Usage in controllers

You can instance a filter in your controller, and define some usefull methods

For example:

  def create_filter(filter_class, opts = {})
      options = { store: session, persist: true }.merge opts
      filter_class.new options
  end

  def filter_params
    if params.has_key?(:filter)
      params.require(:filter).permit(:firstname, :lastname, :cuit).to_options
    end
  end

  # Create the @filter object with the currently-set values for the filters
  def filter
    @filter = create_filter PaymentsFilter, values: filter_params
  end

  # Clear the currently-set filters, restoring them to the defaults
  def clear_filter
    if params[:commit] == t('common.filters.clear')
      @filter.clear!
      redirect_to request.path
    end
  end

### Usage in views

Define a input with the filter

<%= form_tag do %>
    <%= label :filter, :firstname %>
    <%= submit_tag t('common.filters.search' %>
    <%= submit_tag t('common.filters.clear' %>
<% end %>