I’ve been working on an application lately that has a lot of advanced
search and filtering functionality (with ranges and substring searches
for each attribute). Despite being a pretty common use case, this isn’t
supported particularly well by any framework I’ve used, including Rails.
I’d like to fix that. 
Right now, my major pet peeves are:
-
Long, ugly, repetitive methods that check each criterion for
nil/empty and then append to arrays of join tables, conditions and
condition variables. -
Unsettling mix of model and controller responsibility when
constructing Paginators -
Reduced form helper support for form elements that aren’t linked to a
model class -
A bit too much ugly code necessary to get pagination links to send
along the original search params -
No built in support for sortable table headers (okay, so this one is
easy to implement… but still… it would be so easy to add the magic)
My current plan of attack is to add a few helper methods and extend
ActiveRecord and Pagination to support these search features in a more
elegant way.
For example, imagine you could do something like:
@bobs = Person.search(:min_birth_date => ‘2002-05-01’,
:max_birth_date => ‘2003-05-01’,
:first_name_like => ‘obert’,
:last_name_starts_with => ‘Mac’,
:gender => ‘Male’)
and have it recognize the “min_”, “max_” and “_like” modifiers and
automatically build a query with the appropriate conditions and
condition variables.
Ideally, this search method would have a way of automatically handling
joins for cross-table criteria, and also of doing a substring “keyword”
search across several named fields. All of this would be made to work
with paginate as well.
On the view side, a simple helper could write out column header links
that would rerun the search with the correct order_bys. A switch on the
existing pagination_links helper would tell it to include all of the
criteria params from the original search. A basic search method/page
could be generated as part of scaffold (for those who use it as a
reference).
Has anyone already done something similar? Or solved this problem in a
more elegant way? If so, I’d love to hear about it!
If not, I may take a stab at this over the holidays and see what I come
up with. Let me know if you want to help!
Cheers,
Erin