Skip to content
Painless ActiveRecord list filtering for Rails.
Ruby
Find file
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
lib
tasks
test
MIT-LICENSE
README.rdoc
Rakefile
init.rb
install.rb
uninstall.rb

README.rdoc

ListFilter

Painless list filtering for Rails.

You have a view that shows a large list of records. You want to give your users the ability to filter the results using checkboxes, pulldown selects, text search, etc. You might also want the user's filter settings to stay in the session, so that when they go back to the list of records, their settings are retained.

ListFilter does all of this for you. It gathers up the params from the filter form, stores them in the session (when appropriate), and builds the SQL conditions to constrain the list tof records based on the user's filter.

Example

Okay so lets say you have a large list of books. You want your users to be able to filter by author (by id), title (text search), and by year of publication.

Here's what you put in your Controller:

class BooksController < ApplicationController
  def index
    @filter_by = ListFilter.new(self)
    @filter_by.filter_by(:author_id)
    @filter_by.filter_by(:title, :sql => "title LIKE "%?%")
    @filter_by.filter_by(:min_year_of_publication, :sql => "year >= ?")
    @filter_by.filter_by(:max_year_of_publication, :sql => "year <= ?")

    @books = Book.find(:all, :conditions => @filter_by.conditions)
    @authors = Author.find(:all)
  end
end

And here's your view:

<% form_for(:filter_by, :html => {:method => :get}) do |f| %>
  <dl>
    <dt>Author:</dt>
    <dd><%= f.select(:author_id) %></dd>

    <dt>Title:</td>
    <dd><%= f.text_field(:title)</dd>

    <dt>Year of Publication:</dt>
    <dd><%= f.text_field(:min_year_of_publication) %> to <%= f.text_field(:max_year_of_publication) %></dd>
  </dl>

  <%= f.submit("Filter")  %>
<% end %>

<table>
  <thead>
    <tr>
      <th>Title</th><th>Author</th><th>Year</th>
    </tr>
  </thead>
  <tbody>
    <% @books.each do |book| %>
      <tr>
        <td><%= book.title %></td>
        <td><%= book.author %></td>
        <td><%= book.year %></td>
      </tr>
  </tbody>
</table>

That's it. When the user clicks the “Filter” button, the ListFilter will process their filter options, store them in the session, and generate the appropriate SQL conditions.

One thing to watch out for – make sure that the name of your form in your view (form_for(:filter_by, …) corresponds to the variable name in your controller (@filter_by).

Have a look at the #filter_by docs for details on the kinds of options you can specify.

Copyright & License

Copyright © 2010 Matt Zukowski, released under the MIT license

Something went wrong with that request. Please try again.