Rails-Flavored Ruby
Grounded in examples from Chapter 3, this chapter explores some elements of Ruby important for Rails. Ruby is a big language, but fortunately the subset needed to be productive as a Rails developer is relatively small. Moreover, this subset is different from the usual approaches to learning Ruby, which is why, if your goal is making dynamic web applications, I recommend learning Rails first, picking up bits of Ruby along the way. To be a Rails expert, you need to understand Ruby more deeply, and this book gives you a good foundation for developing that expertise. As noted in Section 1.1.1, after finishing Rails Tutorial I suggest reading a pure Ruby book such as Beginning Ruby, The Well-Grounded Rubyist, or The Ruby Way.
This chapter covers a lot of material, and it's okay not to get it all on the first pass. I'll refer back to it frequently in future chapters.
4.1 Motivation
As we saw in the last chapter, it's possible to develop the skeleton of a Rails application, and even start testing it, with essentially no knowledge of the underlying Ruby language. We did this by relying on the generated controller and test code and following the examples we saw there. This situation can't last forever, though, and we'll open this chapter with a couple of additions to the site that bring us face-to-face with our Ruby limitations.
4.1.1 A title Helper
When we last saw our new application, we had just updated our mostly static pages to use Rails layouts to eliminate duplication in our views (Listing 4.1).
Listing 4.1. The sample application site layout.
app/views/layouts/application.html.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Ruby on Rails Tutorial Sample App | <%= @title %></title> </head> <body> <%= yield %> </body> </html>
This layout works well, but there's one part that could use a little polish. Recall that the title line
Ruby on Rails Tutorial Sample App | <%= @title %> |
relies on the definition of @title in the actions, such as
class PagesController < ApplicationController def home @title = "Home" end . . . |
But what if we don't define an @title variable? It's a good convention to have a base title we use on every page, with an optional variable title if we want to be more specific. We've almost achieved that with our current layout, with one wrinkle: As you can see if you delete the @title assignment in one of the actions, in the absence of an @title variable the title appears as follows:
Ruby on Rails Tutorial Sample App | |
In other words, there's a suitable base title, but there's also a trailing vertical bar character | at the end of the title.
One common way to handle this case is to define a helper, which is a function designed for use in views. Let's define a title helper that returns a base title, "Ruby on Rails Tutorial Sample App", if no @title variable is defined, and adds a vertical bar followed by the variable title if @title is defined (Listing 4.2).1
Listing 4.2. Defining a title helper.
app/helpers/application_helper.rb
module ApplicationHelper # Return a title on a per-page basis. def title base_title = "Ruby on Rails Tutorial Sample App" if @title.nil? base_title else "#{base_title} | #{@title}" end end end
This may look fairly simple to the eyes of an experienced Rails developer, but it's full of new Ruby ideas: modules, comments, local variable assignment, booleans, control flow, string interpolation, and return values. We'll cover each of these ideas in this chapter.
Now that we have a helper, we can use it to simplify our layout by replacing
<title>Ruby on Rails Tutorial Sample App | <%= @title %></title> |
with
<title><%= title %></title> |
as seen in Listing 4.3. Note in particular the switch from the instance variable @title to the helper method title (without the @ sign). Using Autotest or spec spec/, you should verify that the tests from Chapter 3 still pass.
Listing 4.3. The sample application site layout.
app/views/layouts/application.html.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <title><%= title %></title> </head> <body> <%= yield %> </body> </html>
4.1.2 Cascading Style Sheets
There's a second addition to our site that seems simple but adds several new Ruby concepts: including style sheets into our site layout. Though this is a book in web development, not web design, we'll be using cascading style sheets (CSS) to give the sample application some minimal styling, and we'll use the Blueprint CSS framework as a foundation for that styling.
To get started, download the latest Blueprint CSS. (For simplicity, I'll assume you download Blueprint to a Downloads directory, but use whichever directory is most convenient.) Using either the command line or a graphical tool, copy the Blueprint CSS directory blueprint into the public/stylesheets directory, a special directory where Rails keeps stylesheets. On my Mac, the commands looked like this, but your details may differ:
$cp-r
|
Here cp is the Unix copy command, and the -r flag copies recursively (needed for copying directories). (As mentioned briefly in Section 3.2.1, the tilde ~ means "home directory" in Unix.)
Once you have the stylesheets in the proper directory, Rails provides a helper for including them on our pages using Embedded Ruby (Listing 4.4).
Listing 4.4. Adding stylesheets to the sample application layout.
app/views/layouts/application.html.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <title><%= title %></title> <%= stylesheet_link_tag 'blueprint/screen', :media => 'screen' %> <%= stylesheet_link_tag 'blueprint/print', :media => 'print' %> </head> <body> <%= yield %> </body> </html>
Let's focus on the new lines:
<%= stylesheet_link_tag 'blueprint/screen', :media => 'screen' %> <%= stylesheet_link_tag 'blueprint/print', :media => 'print' %> |
These use the built-in Rails helper stylesheet_link_tag, which you can read more about at the Rails API.2 The first stylesheet_link_tag line includes the stylesheet blueprint/screen.css for screens (e.g., computer monitors), and the second includes blueprint/print.css for printing. (The helper automatically appends the .css extension to the filenames if absent, so I've left it off for brevity.) As with the title helper, to an experienced Rails developer these lines look simple, but there are at least four new Ruby ideas: built-in Rails methods, method invocation with missing parentheses, symbols, and hashes. In this chapter, we'll cover these new ideas as well. (We'll see the HTML produced by these stylesheets included in Listing 4.6 of Section 4.3.4.)
By the way, with the new stylesheets the site doesn't look much different from before, but it's a start (Figure 4.1). We'll build on this foundation starting in Chapter 5.3
Figure 4.1 The Home page with the new Blueprint stylesheets.