Practical 3
0. Finish Practical Sheet 2. Run the tests (rake test
) to make
sure everything works fine.
1. Controllers. A controller is responsible for a specific part of
an application, and consists of Ruby code that defines methods for the
actions in this part of the application. The part that needs to be
designed now is how our online store presents itself to a potential
buyer, i.e., the catalog. Let’s call the user facing part of the
application the store
. Let’s make the catalog visible to the user
through an index
action. An action consists of three things: a
route, a controller method and a view template. The command
rails generate controller store index
will create a file store_controller.rb
which defines a class StoreController
.
Find the file, and describe what’s in there. Then point your browser to
http://localhost:3000/store/index
to see the effect of issuing the index
command to the store
controller of your application.
This works, because the rails generate controller
command
has set up a new route by adding the line get store/index
to the routes in
the file config/routes.rb
, so that the application now responds to
GET store/index
HTTP requests.
1a. If all works fine, it might be a good idea to commit the current state of the files that make up the depot application to the repository.
git add .
git commit -m "generated store controller"
git push
2.
While you look at the file routes.rb
you might as well modify it
so that the catalog becomes the home page of our application:
replace the line get store/index
by
the line
Then reload the page localhost:3000
. Can you see the shiny product
listing? Why not?
3. In order to properly wire up the store/index
action, a few
files will need to be modified.
For now, the store controller contains only a skeletal definition of
an index
method. Add the line
to that method (i.e., before the first end
). Here, Product
is our
old product model, and order
is a method that applies to the Product
class
and creates a list of all products in the database, ordered by their
title. This list is assigned to the instance variable @products
,
so it becomes part of the instance of the controller that deals with
store/index
requests. Reload localhost:3000
. Any visible change?
Why not?
4. Recall that an action consists of three things: a route, a controller method and a view template. We’ve set up the route at the beginning of this practical. We have defined the controller method in the previous step. Now, let’s update the view template: replace the store index view template (which file?) by
This mixture of HTML and Ruby (enclosed in <%
and %>
)
essentially sets up a loop over the list @products
and displays each product in turn, inside a <li>
element
of an unordered list (<ul>
). How does the browser know how to
format these elements?
How does the view know about the @products
variable?
Reload the page, and now find the catalog.
4a. If all works fine, commit the changes to your local git
repository, and push them to the github
cloud:
git add .
git commit -m "added a store index action"
git push
5. Still, the catalog could look much nicer. Let’s apply some
styling. Open the file app/assets/stylesheets/store.scss
(which was automatically generated by the last rails
command) and add
to its bottom. This bracket provides a place, where all the style
information relating to elements of class store
can be collected.
6. Add the following, bit by bit, into that bracket (i.e. between
{
and }
) and reload the catalog page after each line to see its
effect.
6a. If all looks well, update the repository and push to the cloud.
git commit -a -m "added and styled catalog view"
git push
7. Layouts.
A layout is an HTML frame that applies to
a whole range of pages. Ours is in app/views/layouts/application.html.erb
.
It contains the
required <html>
, <head>
, and <body>
elements, and
sets the title of the browser window.
Edit the <title>
element in the <head>
to look like
If you followed the instructions in Practical 1, and the file contains
then replace these 3 lines by
Then add just below the <body>
tag,
This adds a banner consisting of an image and some text to the top of the page. For this to work as intended, download the file
from http://schmidt.nuigalway.ie/cs424/depot and copy it into the corresponding location inside your own depot application.
8. Rename the file app/assets/stylesheets/application.css
to app/assets/stylesheets/application.scss
(how?)
and add the following to it, bit by bit, and watch the effects:
The empty .content { }
bracket will be filled in the next step.
9. In the layout file, app/views/layouts/application.html.erb
,
add the following after the <header>
element:
and, just before the </body>
end-tag:
This adds a sidebar with a list of (mock) links to the page. In order to
have this blend in with the rest, we add some more style to
app/assets/stylesheets/application.scss
, inside the .content { }
bracket:
and:
and:
and finally:
Again, if you add this line by line (taking care that all opening braces are always matched by closing ones), you can watch the effects of the individual rules.
10.
What’s wrong with the formatting of prices of products?
Find the place where they are printed and
replace product.price
with number_to_currency(product.price)
to fix it.
Sometimes it can be useful to try out a newly found functionality in a separate environment.
The rails console is such a place. It allows you to interact with your
application from a command line. Type (in the top depot
folder)
rails console
to start it up.
The price formatting helper method can be accessed
as helper.number_to_currency
inside the rails console.
Google the documentation of number_to_currency
and
experiment with its options. How can you make it print four billion
euro, with groups of three digits separated by spaces?
10a. If all works fine, commit the changes to your local git
repository, and push them to the github
cloud.
11. Functional Testing.
Functional tests can be used to verify that the model, view and controller
work well together.
The command assert_select
is
something like the Swiss army knife for functional testing.
It allows you to test properties of specific nodes in the document tree.
Add the
following four examples of its use to the "should get index"
test
in the file
store_controller_test.rb
(which directory?):
These tests use CSS selector notation to refer to parts of the HTML that is
returned. The first selects all <a>
elements which sit
inside a <nav>
element with attribute class="side_nav"
and expects to find at least 4 of them
(where?).
The remaining tests verify that all products
(as specified for test purposes in the file fixtures.yml
)
are displayed: there should be 3 <li>
elements
inside an <ul>
element with attribute class="catalog"
,
one <h3>
element should contain the text 'Book1'
,
and all elements with attribute class="price"
should be formatted
as dollar prices.
12. Add a date and time to the sidebar. Formulate a test that checks its presence.
12a. If all works fine, commit the changes to your local git
repository, and push them to the github
cloud.
Any comments or questions? Use the comment box below.