Home > filters

filters

Filters is a project mainly written in Ruby, it's free.

An easy way to filter ActiveRecord object's collection.

h1. Filters

L'objectif de la bibliothèque filters est de faciliter le filtrage d'une collection d'objets ActiveRecord.

L'adaptation à d'autres ORM ne devrait pas être bien compliquée.

h2. Côté vue

<% form_tag(bills_path, :method => :get) do -%>

<%= label_tag "bill_created_at", "Créée à partir du" %>: <%= filter_text_field :bill, :created_at, { :type => :ge }, { :class => "date" } %>

<%= label_tag "bill_state", "Etat" %> <%= filter_select(:bill, :state, { :values => [["Payé", "paid"], ["Non payé", "unpaid"]] }) %>

<%= label_tag "bill_reference", "Référence" %> <%= filter_text_field :bill, :reference %>

<%= submit_tag "Filtrer" %>

<% end -%>

h2. Côté controller

def index
  @bills = Bill.filter(params)
end

C'est tout.

h2. Associations

Filters permet aussi de filtrer sur des associations. Par exemple pour chercher les factures d'un client:

<%= label_tag "company_name", "Client" %>: <%= filter_text_field :company, :name, { :type => :rl } %>

Le type rl désigne un right like, c'est à dire que l'on aura du SQL du genre:

company.name LIKE "foo%"

La liste des types comprend:

  • eq => equal,
  • ne => not equal,
  • li => left and right like,
  • ll => left like,
  • rl => right like,
  • gt => greater than,
  • lt => lower than,
  • ge => greater or equal than,
  • le => lower or equal than

L'option par défaut est eq.

L'option use_blank permet de spécifier si l'on doit quand même utiliser le filtre quand il est vide. Par défaut use_blank est à false.

Si le nom de l'association est customer et qu'il mappe une table companies cela fonctionnera quand même.

C'est le nom de l'association qui doit être utilisé dans la vue mais c'est bien le nom de la table qui sera utilisée dans le filtre.

h2. Valeur vide

Par défaut une valeur vide ne créera simplement pas de filtre, elle est donc généralement utilisée pour récupérer tous les résultats. Si vous souhaitez utilisez la valeur vide en tant que telle dans le filtre il faudra utiliser l'option use_blank, et la mettre à true.

h3. Combiner valeur vide et tous

Comme mentionné au dessus, utiliser use_blank empêche de récupérer l'intégralité des résultats.

Pour avoir une option dans un select qui propose de sélectionner tous les résultats quand use_blank est à true il faut spécifier la valeur à :* (Filter::Model::ALL)

<%= label_tag "bill_state", "Etat" %> <%= filter_select(:bill, :state, { :values => [["Tous", ":*"], ["Vide", ""]], :use_blank => true }) %>

h2. Intervalles

Il est possible de définir des intervalles de recherche de valeurs.

<%= label_tag "bill_created_at_after", "Créée entre le:" %>: <%= filter_text_field :bill, :created_at_after, { :type => :ge, :reference => :created_at } %>

<%= label_tag "bill_created_at_before", "et le:" %>: <%= filter_text_field :bill, :created_at_before, { :type => :le, :reference => :created_at } %>

Il est par contre impératif que le nom des champs utilisés ne soit pas le même, sous peine de comportement «étrange».

L'option reference permet de définir sur quel champ la recherche va s'appliquer. Rien n'empêche donc de faire plusieurs filtres sur un même champ.

h2. Filters fonctionne t-il avec will_paginate ?

Oui. Seule l'invocation côté controller change. De façon plus générale filter permet de repasser toutes les options d'un find classique.

@bills = WillPaginate::Collection.create(params[:page] || 1, 10) do |pager|
  @bills_count = Bill.filter_count(params)
  results = Bill.filter(params, { :limit => pager.per_page, :offset => pager.offset })

  pager.replace(results)
  pager.total_entries = @bills_count
end

h2. Sécurité

Il est important de savoir ce que vous faites lorsque vous utilisez filters. En effet potentiellement rien n'empêche un utilisateur de modifier les paramètres envoyés pour filtrer les résultats (même pour un formulaire de type POST).

Des paramètres pourraient donc être envoyés pour filtrer des champs que vous n'aviez pas prévu.

De même il suffit de modifier le paramètre référence pour changer le comportement d'un filtre et le faire filtrer un autre champ.

Pour palier à cela les prochaines versions permettront de définir explicitement quels champs ne peuvent pas être filtrés.