Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby on Rails: Search Form - multiple search fields

I am trying to create an application that allows the user to search a database. The search page layout would behave with some drop down menus that would show data already in the database to narrow the search, and also text boxes to allow the user to put in key words like the "project name". I'm having a problem getting rails to take all the info that has been entered in the search form, and performing one big search.

Here is part of my search layout:

<%= form_tag search_path, :method => 'get' do %>

<%= hidden_field_tag :direction, params[:direction] %>
 <%= hidden_field_tag :sort, params[:sort] %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search Project Name", :project_name => nil %>
</p>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search Client", :client => nil %>
</p>
<% end %> 

Here is my index and search actions in the project controller:

def index
@projects = Project.all

respond_to do |format|
  format.html # index.html.erb
  format.json { render :json => @projects }
 end
end

def search

@project_search = Project.search(params[:search]).order(sort_column + ' ' + sort_direction).paginate(:per_page => 5, :page => params[:page])


end

and here is part of my models/project.rb file

def self.search(search)
if search
  where('project_name LIKE ?', "%#{search}%") || where('client LIKE ?', "%#{search}%")
else
  scoped
end
end

As you can see, I am just trying to search on either the project_name or the client. If I can get this working, I will be extending it onto other fields.

The functionality at the moment is that, when I try to search it both boxes, it overwrites one, and only does one of the field searches.

I am brand new to ROR so hopefully someone can help. Any suggestions will be appreciated.

Thanks in advance!

like image 471
Jazz Avatar asked Jul 20 '12 10:07

Jazz


2 Answers

This problem has been solved in another question: Ruby on Rails: Advanced search

Based on your question, @Chris Wise is assuming that you have two columns in your projects table: project_name and client.

I might be wrong, but I think you actually have two models Client and Project, where a client has many projects. If so, you need to define the search in each model:

Client model:

def self.search search_term
  return scoped unless search_term.present? 
  where(['client_name LIKE ?', "%#{search_term}%"]) #client_name means the column name, change it to the correct name.
end

Project model:

def self.search search_term
  return scoped unless search_term.present? 
  where(['project_name LIKE ?', "%#{search_term}%"]) #project_name means the column name, change it to the correct name.
end

Your form:

<%= form_tag projects_path, method: :get do %>
  <%= text_field_tag :project_name, params[:project_name] %>
  <%= text_field_tag :client, params[:client] %>
  <%= submit_tag "Search", name: nil %>
<% end %>

Then your controller:

#return all projects that match the search criteria
@project_search = Project.search(params[:project_name]).all
#return all clients that match the search criteria
@clients_search = Client.search(params[:client]).all

I hope it helps...

like image 154
gabrielhilal Avatar answered Nov 03 '22 11:11

gabrielhilal


I'd like to suggest a few things that you might want to do. First off, having a search method in addition to the index method in your controller is unnecessary as they are both rendering a collection of Projects.

So first off, I would change:

<%= form_tag search_path, :method => 'get' do %>

to

<%= form_tag projects_path, :method => 'get' do %>

This will call the index method instead.

I'd next suggest putting the search logic itself into the model.

In your Project class, add the following method:

def self.search search_term
  return scoped unless search_term.present?
  where(['project_name LIKE ? OR client LIKE ?', "%#{search_term}%", "%#{search_term}%"])
end

Finally, modify your controller action for index as follows:

@projects = Project.search(params[:search]).all

Effectively what you are doing is searching only if a term is present and otherwise chaining the scope.

like image 43
Chris Wise Avatar answered Nov 03 '22 13:11

Chris Wise