I wanted the ability to sort my tabular data using column header links. I wanted the links for each column to toggle between ASC and DESC depending on the current sort direction for that column. I also wanted the system to remember the sort order of a given table even after I navigated away from and back to the page that contained it. My current solution is the sortable_column_headers plugin (SCH).
UPDATE: Some significant updates have been made to this plugin as of 2007 06 10. They include:
- Sort solutions now span controllers.
- Multiple sort solutions on a single page are more robust.
- Can override ASC default with DESC.
- Methods now take options as a Hash (backwards compatible!).
- Demo app includes multiple sort solutions and session debug info.
UPDATE: Fixed bug regarding aliases and multiple sort solutions, 2007 06 18.
First, in my controller I tell SCH which fields I want sortable. In the following example, I tell SCH I need to establish a sorting solution called "listing" (to differentiate it from other sorting solutions which may exist on the same page). This solution will sort the "author_id" column in the Book model, and we want our link to be pretty, so please call it "author" (instead of "books.author_id", more on this later).
add_to_sortable_columns('listing',
:model => Book,
:field => 'author_id',
:alias => 'author')
You don't need to specify an alias. Or you can omit the model and specify the field outright (:field => "books.author_id"). You have a lot of options detailed in the README. Also, a single sorting solution can have as many "add_to_sortable_columns" as you need for all the fields returned in your database query. You can bulk add all the fields in a single model like this:
add_to_sortable_columns('listing', :model => Book)
Second, in my view I need to use the "sort_param" method to add the SCH parameter to my links.
<%= link_to 'Author', sort_param('listing', :alias => 'author') %>
The call to "sort_param" in the previous example may produce a URL param like "?sortasc=listing-author". The sorting solution label is always appended to the name of the field, even if you have specified an alias.
Last, going back to my controller, I need to ask SCH for the sorting solution by using the "sortable_order" method. In the following example, I tell SCH I want the solution for "listing", and sort on "books.author_id DESC" by default if the user is viewing the data for the first time.
@books = Book.find :all,
:order => sortable_order('listing',
:model => Book,
:field => 'author_id',
:sort_direction => :desc)
The call to "sortable_order" in the previous example may produce something like "books.author_id DESC".
If you are interested in such things, SCH does some of its magic by storing previous sort orders for each sorting solution in "sessions[:sortable_column_headers]".
You can get it here: https://svn.elctech.com/svn/public/sortable_column_headers/
UPDATE: I put a very small demo Rails application using SCH called (not surprisingly) "sortable_column_headers" in our SVN repository. You can get it here: https://svn.elctech.com/svn/public/demo/sortable_column_headers/
NOTE: This plugin has not been updated for compatibility with Rails 2.2+ but might be in the future. This plugin was written by ELC Alumni and new dad Colman Nady.

Hi, thanks for publishing this. I've just integrated the plugin into my app. and it works as you describe. One thing, most examples of sortable tables provide little arrows to indicate on which column and what direction the table is sorted. Could you provide an example of how this might be implemented?