2

I am a beginner in ROR development. I have navigation and I want search box on every page and when I enter some keyword, it should do like query across table's field. I tried using some online tutorials but could not do it. My table name : tutorials here is my search form on navigation bar

<li><%= link_to 'Login', :controller => 'access', :action => 'login'  %></li>
<li><%= link_to 'Sign Up', :controller => 'users', :action => 'new'  %></li>
<li><%= link_to 'Logout', :controller => 'access', :action => 'logout'  %></li>
<div align="right">
<%= form_tag("/search", method: "get") do %>
  <%= label_tag(:q, "Search for:") %>
  <%= text_field_tag(:q) %>
  <%= submit_tag("Search") %>
<% end %>
</div>

Here is my controller

class SearchController < ApplicationController 

  def show
    @tutorial = Tutorial.find(params[:q])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @tutorial }
    end
  end
end

Here is my model

class Search < ActiveRecord::Base
  def @tutorial.search(search)
    if search
      find(:all, :conditions => ['tutorial_name LIKE ?', "%#{search}%"])
    else
      find(:all)
    end
  end
end

I am not sure how to do this. Please help

Gene
  • 46,253
  • 4
  • 58
  • 96
pritesh
  • 193
  • 1
  • 4
  • 18
  • I'm not sure if passing in `"%#{search}%"` within double quotes will actually work, you might need to just need to do this instead: `['tutorial_name LIKE %?%', search]`. –  Apr 22 '14 at 00:02
  • Related, but may be out of date: [How to do a LIKE query in Arel and Rails 3?](http://stackoverflow.com/q/4430578/456814). See also [Rails 4 LIKE query - ActiveRecord adds quotes](http://stackoverflow.com/q/19105706/456814). –  Apr 22 '14 at 00:03
  • So your current code doesn't work? Do you get any error? If yes, then share the error logs. – Kirti Thorat Apr 22 '14 at 00:07
  • See also item #8 in [this blog post](http://blog.mitchcrowe.com/blog/2012/04/14/10-most-underused-activerecord-relation-methods/), [SQL Like operator in ruby on rails](http://stackoverflow.com/q/13758844/456814), and [Ruby on Rails 2.3 SQL LIKE query](http://stackoverflow.com/q/10916604/456814). –  Apr 22 '14 at 00:09

2 Answers2

15

It's often true that a bad name indicates wrong thinking. I believe your name Search for the model is in this category. It should probably be called Tutorial, no? Search is something you do to a model, not the model itself.

If this guesswork is correct and the model is now called Tutorial and it has a field called name that is a string, then your model will be

class Tutorial < ActiveRecord::Base

  def self.search(pattern)
    if pattern.blank?  # blank? covers both nil and empty string
      all
    else
      where('name LIKE ?', "%#{pattern}%")
    end
  end

end

This makes the model "smart" on how to search through tutorial names: Tutorial.search('foo') will now return all tutorial records that have foo in their names.

So we can create a controller that uses this new functionality:

class SearchController < ApplicationController 

  def show
    @tutorials = Tutorial.search(params[:q])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @tutorial }
    end
  end
end

The corresponding view must display the tutorials. Yours doesn't. The simplest way to do this is write a partial that renders exactly one tutorial. Say it's called _tutorial.html.erb.

Then in the view for Search, you need to add

<%= render :partial => @tutorials %>

to actually display the search results.

Addition

I'll build a little example.

# Make a new rails app called learning_system
rails new learning_system             

# Make a new scaffold for a Tutorial model.
rails g scaffold Tutorial name:string description:text 

# Now edit app/models/tutorial.rb to add the def above.

# Build tables for the model.
rake db:migrate

rails s # start the web server

# Now hit http://0.0.0.0:3000/tutorials with a browser to create some records.

<cntrl-C> to kill the web server

mkdir app/views/shared
gedit app/views/shared/_search_box.html.erb
# Edit this file to contain just the <%= form_tag you have above.

# Now add a header at the top of any view you like, e.g. 
# at the top of app/views/tutorials/index.html.erb as below
# (or you could use the layout to put it on all pages):

<h1>Listing tutorials</h1>
<%= render :partial => 'shared/search_box' %>

# Make a controller and view template for searches
rails g controller search show  

# Edit config/routes.rb to the route you want:  get "search" => 'search#show'

# Verify routes:

rake routes
       search GET    /search/:id(.:format)         search#show
    tutorials GET    /tutorials(.:format)          tutorials#index
              POST   /tutorials(.:format)          tutorials#create
 new_tutorial GET    /tutorials/new(.:format)      tutorials#new
edit_tutorial GET    /tutorials/:id/edit(.:format) tutorials#edit
     tutorial GET    /tutorials/:id(.:format)      tutorials#show
              PUT    /tutorials/:id(.:format)      tutorials#update
              DELETE /tutorials/:id(.:format)      tutorials#destroy

# Edit app/controllers/search_controller.rb as above.

# Create app/views/tutorial/_tutorial.html.erb with following content:
<tr>
<td><%= tutorial.name %></td>
<td><%= tutorial.description %></td>
</tr>

# Edit app/views/search/show.html.erb to have following content:
<h1>Show Search Results</h1>
<table>
<%= render :partial => @tutorials %>
</table>

Now try a little test. Fill in a search criterion and press the Search button.

Gene
  • 46,253
  • 4
  • 58
  • 96
  • Hello Gene, Thanks for your help. I don't understand what should I do with model, should I write this method in tutorial.rb or you want me to rename my search model to tutorial and I tried using your suggestion but I am not sure how do I display my Result? I have created one Index.html.erb file, here is the code for that.

    Tutorial name: <%= @tutorial.tutorial_name %>

    – pritesh Apr 22 '14 at 22:18
  • @Pritesh777 I built a quick and dirty app that ought to serve as a pattern for what you're trying to do. See addition. – Gene Apr 23 '14 at 00:52
  • This answer is so detailed I want to donate money to @Gene. The best teachers are not in classrooms. – Chidozie Nnachor Nov 20 '18 at 17:16
  • 2
    @ChidozieNnachor That's funny. I taught undergrad computer science for 24 years. – Gene Nov 20 '18 at 22:28
  • @Gene, pardon me. I was in awe of the answer. It adds up now. My earlier statement is hereby withdrawn. – Chidozie Nnachor Nov 20 '18 at 23:07
-1

On Rails 6 you can use for search action implementation in the controller.rb:

  def search
    keyword = params[:q] #you can get this params from the value of the search form input
    @posts = Post.where("title LIKE ?", "%#{keyword}%")
  end
viatech
  • 79
  • 1
  • 9