# Advanced search/filter use cases

**URL:** <https://www.ruby-forum.com/t/advanced-search-filter-use-cases/50671>\
**Category:** Rails\
**Created:** [December 19, 2005, 9:32pm UTC](https://www.ruby-forum.com/t/advanced-search-filter-use-cases/50671 "2005-12-19T21:32:19Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Erin\_Mulder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/5f8ce5/32.png) [@Erin\_Mulder](https://www.ruby-forum.com/u/Erin_Mulder)\
**Post date:** [December 19, 2005, 9:32pm UTC](https://www.ruby-forum.com/t/advanced-search-filter-use-cases/50671/1 "2005-12-19T21:32:19Z")

</div>

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:

1. Long, ugly, repetitive methods that check each criterion for  
nil/empty and then append to arrays of join tables, conditions and  
condition variables.

2. Unsettling mix of model and controller responsibility when  
constructing Paginators

3. Reduced form helper support for form elements that aren’t linked to a  
model class

4. A bit too much ugly code necessary to get pagination links to send  
along the original search params

5. 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

---

<div class="post-metadata">

**Author:** ![Erin\_Mulder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/5f8ce5/32.png) [@Erin\_Mulder](https://www.ruby-forum.com/u/Erin_Mulder)\
**Post date:** [December 19, 2005, 10:39pm UTC](https://www.ruby-forum.com/t/advanced-search-filter-use-cases/50671/2 "2005-12-19T22:39:36Z")

</div>

You might have a look at this for the dynamic sql stuff:

[http://brainspl.at/articles/2005/12/02/build-ar-base-finds-conditions-clause-dynamically-take-one](http://brainspl.at/articles/2005/12/02/build-ar-base-finds-conditions-clause-dynamically-take-one)

John

Erin Mulder wrote:

> nil/empty and then append to arrays of join tables, conditions and
> 
> @bobs = Person.search(:min\_birth\_date =\> ‘2002-05-01’,  
> joins for cross-table criteria, and also of doing a substring “keyword”  
> Has anyone already done something similar? Or solved this problem in a  
> [http://lists.rubyonrails.org/mailman/listinfo/rails](http://lists.rubyonrails.org/mailman/listinfo/rails)  
> –  
> John D.  
> Great Basin Development  
> P.O.Box 3503, Reno, Nevada 89505  
> Cell: (775) 772-7336  
> removed\_email\_address@domain.invalid  
> [http://www.gbdev.com/](http://www.gbdev.com/)

---

<div class="post-metadata">

**Author:** ![Erin\_Mulder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/5f8ce5/32.png) [@Erin\_Mulder](https://www.ruby-forum.com/u/Erin_Mulder)\
**Post date:** [December 19, 2005, 11:43pm UTC](https://www.ruby-forum.com/t/advanced-search-filter-use-cases/50671/3 "2005-12-19T23:43:17Z")

</div>

Hi,

I have come across this problem before and it was the main motivation  
for the ActiveForm [1] class that I created. It allowed validations to  
be used for non-activerecord objects. The next step I made a  
ActiveSearch class that defined a bunch of macros similar to

search\_field :type\_id, :foreign\_key  
search\_field :created\_before, :date  
search\_field :created\_from, :period  
search\_field :include\_summary, :boolean  
search\_field :component\_id, :foreign\_key, :join =\> ‘components’  
search\_field :version\_id, :foreign\_key, :join =\> ‘versions’, :join\_key  
=\> ‘affects\_version\_id’  
…

This class also had a gen\_sql that returned two values conditions and  
joins that could be passed onto the paginator or directly into find  
etc. The class also had methods to generate the params from a  
particular search so I could link to it from sorted\_link\_tos or  
paginator links. Of course it added benefit that it did not produce  
param if the value was equivelent to the default. The only thing I  
have yet to complete is correctly generating the order\_bys for join  
tables but I only need that in one place so I have not bothered.

[1]  
[http://www.realityforge.org/articles/2005/12/02/validations-for-non-activerecord-model-objects](http://www.realityforge.org/articles/2005/12/02/validations-for-non-activerecord-model-objects)

–  
Cheers,

Peter D.  
Blog: [http://www.RealityForge.org](http://www.RealityForge.org)
