Lesson 3: Input and Search

Hoping you have entered a few records into the books database, let us now 
see how we can search it. To start with, we go to the root folder of the application,
and type:

script/generate controller search index

We then edit app/controllers/search_controller.rb so that it contains:

class SearchController < ApplicationController
def index
    if @search=params[:search]
@books=Book.find(:all).select do |b|

In the above, we take the contents of the text box indicated by :search (see
view below), assign it to @search. To determine the contents of @books, we load
all the records from the books database into an array, then select only those in whose author
field, the contents of @search, or the search box, are found.

This is what the view app/views/search/index.html.erb need to look like after
editing -- please don't type the line numbers into the editor, they are shown only
for convenience in discussing the contents:

1 <% form_tag(:action=> :index) do %>
2 <p>
3 whom are you searching for: <%= text_field_tag(:search) %>
4 </p>
5 <%= submit_tag("Search") %>
6 </p>
7 <% end %>
8 <% if @books %>
9 books written by <%= @search %>
10 <table border="1">
11 <% @books.each do |b| %>
12 <tr>
13 <td><%= b[:name] %></td>
14 <td><%= b[:author] %></td>
15 </tr>
16 <% end %>
17 </table>
18 <% end %>

Lines 1 and 7 enclose the code for a form that will feed data back to the controller.
On line 5 we insert a Search button into the page, and when it is clicked, the index
method of the SearchController shown above is invoked. Line 3 inserts into the page
a text entry field, which the controller will be able to access as params[:search].
since :search is the parameter passed to text_field_tag.

If @books is defined (line 8)we display a table with two rows, one containing
the name of the book and the other that of the author, lines 13 and 14 respectively.
Lines 11 and 16 ensure that the intervening html is reproduced once for each book,
as typing ri Array.each on the commandline explains:

------------------------------------------------------------- Array#each
array.each {|item| block } -> array
Calls _block_ once for each element in _self_, passing that element
as a parameter.

a = [ "a", "b", "c" ]
a.each {|x| print x, " -- " }


a -- b -- c --

If I therefore go to http://localhost:3000/search and type 'David' into the
search box and press the Enter key, what I see is in the image below -- your
output will of course depends on what data you have fed into the books database
on your computer.
You can, of course, see a complete list of the books you have
entered by pointing your browser to http://localhost:3000/books