Now that we've built an online bookstore application in Ruby-on-Rails, it's time to serve our customers by building a book catalog of the store that they can use for browsing, viewing book details, searching for books, and finding out about new titles at a glance. This article, the first in a three-part series, is excerpted from chapter four of the book Practical Rails Projects, written by Eldon Alameda (Apress; ISBN: 1590597818).
Building an Online Book Catalog - Implementing the Browse Books User Story (Page 3 of 4 )
Now that we have the controller in place, we’re ready to begin with the Browse Books user story.
Modifying the Controller
At this point, we’re interested in only theindexaction and the corresponding view. Openapp/controllers/catalog_controller.rb, which was just created by thegeneratorcommand. Modify theindexmethod so that it looks as follows:
In theindexaction, we first set the page title so that the layout file will pick it up and show it in the headers of the resulting page. Additionally, the action contains a normal pagination call, just as in Chapter 3. However, this time, we use theincludeparameter for thepaginatecall.
Theincludeparameter is used in the ActiveRecordfindmethod (which is used internally bypaginate) to make ActiveRecord build up a join query. This single SQL query will be used not only to find the books, but also to fetch the associated authors and publishers from the database. If we omitted the parameter, our code would end up calling a new SQL query each time we needed to get the author or publisher details for a given book. In our case, it would result in 2n+1 (where n is the number of books) queries instead of just one. When the site gets more traffic, that could become a huge performance bottleneck.
Note We can hear you ask, “Where does the 2n+1 come from?” The first query is the one where all the books are fetched. Then, when we iterate over all the n books and call theirauthors andpublisher methods, each call will result in an additional SQL query, resulting in two additional queries for each book. The resulting amount of queries is thus 2 queries × n books + the original query, or 2n+1.
Modifying the View
Next, openapp/views/catalog/index.rhtmland replace its contents with the following code.
<dl id="books"> <% for book in @books %> <dt><%= book.title %></dt> <% for author in book.authors %> <dd><%= author.last_name %>, <%= author.first_name %></dd> <% end %> <dd><%= pluralize(book.page_count, "page") %></dd> <dd>Price: $<%= sprintf("%.2f", book.price) %></dd> <dd><small>Publisher: <%= book.publisher.name %></small></dd> <% end %> </dl>
In the view, we iterate over all the books we got from the controller and show their titles, authors, prices, page counts, and publishers. Thepluralizehelper will show the word “page” in either singular or plural, depending on the value ofbook.page_count. In the end, we show links to next and/or previous page in case there are more than ten books in the@booksarray.