1

I am currently implementing the search functionality in a project and I am struggling displaying it on a dedicated search result page.

Being aware of questions on this topic already but being unable to work out a solution due to utter incompetence, I am asking you for the final pointer :).

The search form spawns on the index page which is entries_path and root_path. I'd like to pass on the parameters to a new page, search_path.

Here are my files:

EntriesController

def search
end

def index
  @entries = Entry.all.order('entries.created_at DESC')
  @entry = Entry.new # My index page also creates new entries.

  if params[:search]
    @entries = Entry.search(params[:search]).order("created_at DESC")
  else
    @entries = Entry.all.order("created_at DESC")
  end

Model: entry.rb

def self.search(search)
  where("content LIKE ? OR created_at LIKE ?", "%#{search}%", "%#{search}%") 
end

routes.rb

Rails.application.routes.draw do
  resources :entries 
  root                  'entries#index'  
  get   'new'       =>  'entries/new'
  get   'show'      =>  'entries/show'
  get   'edit'      =>  'entries/edit'
  get   'search'    =>  'entries/search'

Finally: the form on index

<%= form_tag(entries_path, :method => "get", class: "search-form") do %>
  <%= text_field_tag :search, params[:search], placeholder: "Search for previous entries..", class: "form-control" %>
<% end %>

When I change the entries_path to search_path, I am getting a "We're sorry, but something went wrong. If you are the application owner check the logs for more information." – therefore, I suspect it is a routing problem. However, I can't seem to figure it out. The log says:

ActionController::RoutingError (uninitialized constant Entries):

Phew, would love to know what's going on here! Thanks a bunch already.

Thierry M.
  • 113
  • 1
  • 15

2 Answers2

2

Change your routes.rb

Rails.application.routes.draw do
  root                  'entries#index'
  resources :entries  do
    collection do
      get :search
    end
  end
end

change your path in search form on index page:

<%= form_tag(search_entries_path, :method => :get, class: "search-form") do %>
  <%= text_field_tag :search, params[:search], placeholder: "Search for previous entries..", class: "form-control" %>
<% end %>

Change your controller's method:

def search
  if params[:search]
    @entries = Entry.search(params[:search]).order("created_at DESC")
  else
    @entries = Entry.all.order("created_at DESC")
  end
end

create one template for search method under view/entries/search.html.erb You can here access your @entries object


Points of changes I have made:

1. Changes in routes.rb:

Rails router recognizes URLs and dispatches them to a controller's action. It can also generate paths and URLs, avoiding the need to hardcode strings in your views. A resource route maps a number of related requests to actions in a single controller. a resourceful route provides a mapping between HTTP verbs and URLs to controller actions. By convention, each action also maps to particular CRUD operations in a database. for more information regarding routes

You can add additional routes that apply to the collection or individual members of the collection.

For Eg:

To add a member route, just add a member block into the resource block:

resources :entries do
  member do
    get 'preview'
  end
end

To add a route to the collection:

resources :entries do
  collection do
    get 'search'
  end
end

A member route will require an ID, because it acts on a member. A collection route doesn't because it acts on a collection of objects. for more info about difference between collection route and member route in ruby on rails?

2. Which method should I use for search GET or POST?

There are numbers of post available regarding GET and POST request on the web as well as SO. GET and POST both have their place, and if you’re a Web developer you should understand the pros and cons of each of them. Or if you’re too lazy to do that, just remember that Search forms should use GET method. Your users will appreciate it. ;)

Let me define them in short description. GET to fetch a resource(when you don't want to make any change in your DB), POST to create a resource(when you want to make a change/create in your DB), PUT (or PATCH, these is debate on the matter) to update a resource, DELETE to delete one.

For your reference:

I hope this information may helps you. Good Luck :)

Community
  • 1
  • 1
Gagan Gami
  • 10,121
  • 1
  • 29
  • 55
0

You could use html as a search field on Index page.

<form>
  <legend>Search</legend>
  <div class='col-xs-4'>
    <input type='text' class='form-control' value='<%= params[:search] %>' name='keyword' placeholder='Keyword' >
  </div>
</form>

Note: This form would hit your index action of entries controller, So at this point no need to create a search methods as you have created

Gupta
  • 8,882
  • 4
  • 49
  • 59