# General ways to create a filterable search

**URL:** <https://www.ruby-forum.com/t/general-ways-to-create-a-filterable-search/164702>\
**Category:** Rails\
**Created:** [April 4, 2009, 9:07am UTC](https://www.ruby-forum.com/t/general-ways-to-create-a-filterable-search/164702 "2009-04-04T09:07:47Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![scudco](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/aca169/32.png) [@scudco](https://www.ruby-forum.com/u/scudco)\
**Post date:** [April 4, 2009, 9:07am UTC](https://www.ruby-forum.com/t/general-ways-to-create-a-filterable-search/164702/1 "2009-04-04T09:07:47Z")

</div>

Ive done a lot of searching on this and found lots of topics on what  
search tools to use but couldnt find something re: how you generally  
implement search into your project regardless of the choice of tool  
(ferret etc).

I want users to be able to do a basic search and if they want supply  
some extra conditions. I return the results and the user can further  
filter those results by checking boxes, entering min max values etc. The  
results are filtered instantly as happens instantly via ajax like  
[kayak.com](http://kayak.com) without reloading the page(great site for airtickets by the  
way) does. Im just wondering generally how i go about this. As you will  
find out I dont have the vaguest of ideas on how.

Assuming i have a products model

Do I create a search model with no db attached (im expecting a lot of  
searches and encouraging users to use the refine function - i dont  
expect saving searches to be useful as per a railscast i saw)? within  
this i create some methods such as (excuse the semi pseudo code cant  
remember exact syntax)

class Search

def self.search(some\_conditions)  
Product.find(:all with some\_conditions)  
end

end

I assume ill have a form\_tag for my search field and optional condition  
fields. This will be on my products index view.

Where should the form\_tag url link to? To products controller? cretae a  
search method over there?

##Products controller  
def search  
@search\_results\_of\_products = Search.search(params[:search\_query]  
end

What about when i wnat users to be able refine the results even further.  
Do I need to another form for this use? Would it link back to the search  
function i defined earlier and ammend the code or would i create a new  
method called refine? Would I basically just hit the db again but with  
the new “more refined” terms or do I use ruby to just get rid of the  
unwanted results from the ones i found previously.

Lots of questions. Im sorry. If you know of a good primer on this Id be  
greatful. Id like to see how code is organised.

---

<div class="post-metadata">

**Author:** ![scudco](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/aca169/32.png) [@scudco](https://www.ruby-forum.com/u/scudco)\
**Post date:** [April 6, 2009, 6:45am UTC](https://www.ruby-forum.com/t/general-ways-to-create-a-filterable-search/164702/2 "2009-04-06T06:45:26Z")

</div>

You are asking about some basic programming issues, so this is  
targeted that way.

You will do well to implement session variables here. You will need to  
capture the user’s selected options in the session and reflect those  
choices back to the form when the page is redrawn. You can use the  
same form as the original search. You can have separate session  
variables for each parameter or collect them in a hash. It may be  
easier to work with separate variables, depending on your experience.

Use whatever controller you want to analyze the selected options and  
build or select which query to use.

For those who have never done this, suppose one of the options was an  
integer for size. You would pass params[:option\_a] or params[:search]  
[:option\_a] to your controller. In the target action, you would set:

```
 # setting a session variable from form input; since all

```

parameters are of the form string,  
# you need to convert it if you want an integer. This is done for  
illustrative purposes here,  
# as a string data type could just as well be used in the  
database unless you were doing some math  
# operation in the database. If you were passing an id, you would  
need  
# to make sure it was an integer when passed to the query  
session[:option\_a] = params[:search][:option\_a].to\_i

Then you would run the appropriate query such as:

```
 # using '?' makes SQL injection attacks more difficult
 @filter = Product.find_by_sql(["SELECT * FROM products WHERE

```

size=?",session[:option\_a]])

In the view containing the form, you would make session[:option\_a]  
available to the appropriate input:

\<% size = ‘’  
unless nil == session[:option\_a]  
size = session[:option\_a].to\_s # it would typically work here  
without the conversion method  
end %\>  
\<input type=text name=‘option\_a’ value=\<%= size -%\> \> …or the  
rails form\_helper equivalent.

This allows you to use the same form and to remember the previous  
input through each iteration.

You will also want to be familiar with input validation techniques to  
handle mistakes and input from users who might try to use your site in  
unintended ways. You will need to use HTMLEntities for text values,  
even if you use an option list to submit data:

```
 def search_me
 # the name for the session variable and the parameter don't have

```

to match, but it makes programming easier  
session[:color] =\> HTMLEntities.encode\_entities(params[:product]  
[:color], :basic, :named)  
…code  
end

and in the form:

\<% user\_text = ‘’  
unless nil == session[:color]  
user\_text = HTMLEntities.decode\_entities(session[:color])  
end %\>  
… etc

You can define searches in your model or controller (or view), but  
searches should be called from the controller. If you try to define a  
search in the model using session[:option\_a], it will not work.

model  
self.find\_tea\_and\_crumpets(flavor)

controller  
def breakfast  
find\_tea\_and\_crumpets(session[:flavor])

This does not answer all your questions, but maybe will help someone.

* * *

One of the big problems for programmers new to the MVC model is “what  
goes where?”. There are various opinions, but much of it is up to you.  
As you experiment, you will need tools to expose the state of your  
application and what variables are being passed. To make the most of  
the framework, you will need to follow rails idioms as closely as  
possible, but it is not always possible with complex scenarios.

You can view the form variables being passed in the logger and you can  
use session/console to test your queries. Here is a handy accessory  
for this type of work:

[http://snippets.dzone.com/posts/show/697](http://snippets.dzone.com/posts/show/697)

There is also the TextMate Footnotes plugin. Either of these may  
require some ‘advanced’ tinkering to work satisfactorily.

You should also be familiar with logger.debug(). There is a RailsCast  
on using bindings with logger.debug - very handy.

* * *

If there are any advanced programmers reading this, please feel free  
to offer corrections or better ideas.

On Apr 4, 3:07 am, Adam A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)
