Lewis Cawthorne

AWDWR 5.1 - 02 - Instant Gratification

18 May 2017

First I’ld like to say sorry the images are a little big. Not used to screencaps on this retina Macbook.

So, I fixed my mistake from last time. I had originally installed ruby via homebrew, but now that I’ve read up on rbenv, it seems a lot nicer than the old rvm, and I might want multiple versions of Ruby on my home PC. So I uninstalled Ruby 2.4 and went with brew install rbenv and then used it to install the latest Ruby. I see why the book authors prefer it over RVM now. It’s a lot less invasive than the old RVM.

Anyway, on with Chapter 2, “Instant Gratification”. I went ahead and completed the code for this chapter and the exercises. Both were fairly trivial. I checked it in at demo51. If you clone that and run bin/rails server from the directory, you’re greeted by the site at http://localhost:3000/. You get a lot for very little with Rails. The site you get just from running rails new demo51 looks like this:

rails welcome

It also looks like the default server has changed from WEBrick to Puma now. But a page with a picture isn’t all that impressive. I must say that I find it pleasant how fast the server starts. I’ve become used to my Java EE servers with multiple minute startup times before you can see changes, but not only does this server start fast, it loads changes on the fly when in development mode, so you seldom have to restart it. What is also impressive is how easy it is to modify with a new route. What is slightly intimidating is that the rails new command actually generated forty-six files spread across thirty-four directories. The nice thing is that everything is in its proper place, and hopefully by reading this book and working with the applications a bit more we’ll come to understand the logic behind it.

The whole application in this chapter is a Hello World modified with a timestamp to show something dynamic. To do this, we need to generate a new controller. Going to the directory of our app and running bin/rails generate controller Say hello goodbye will generate a controller named Say with methods (in Rails terms, these controller methods are called actions) hello and goodbye that will respond to requests to /say/hello and /say/goodbye. It puts the say controller in demo51/app/controllers/say_controller.rb. This is the controller that contains methods for all the /say/ routes. Its starting code that was generated is simply:

class SayController < ApplicationController
  def hello
  end

  def goodbye
  end
end

Those methods obviously don’t do much. Because it inherits from ApplicationController, our SayController automatically gets all the default controller behavior. Even though the controller methods don’t have any logic, they still return a site when you navigate to the URL, because by convention they are associated with certain views.

Say#hello

The route informs of the file it is currently serving app/views/say/hello.html.erb, which was also automatically generated when we created our controller with the command above. If we edit the file it points us to, we find what looks like a normal html file body:

<h1>Say#hello</h1>
<p>Find me in app/views/say/hello.html.erb</p>

This is the view that was generated by our command. The views for the SayController we created by default are placed in the app/views/say directory, and there is a view for each of the hello and goodbye methods. The book has us change this view to instead say:

<h1>Hello from Rails!</h1>

If we refresh our browser window (without restarting the server), we see the new output:

Hello from Rails

So far, we’ve learned the place two things go. Controllers go in app/controllers and views go in app/views. The book shows it with the diagram:

directory structure

The book goes on to add the time display to the page directly, then refactor it to have the time generated by the controller and displayed in the view. We’ll just skip to that. We modify say_controller.rb to generate the time:

class SayController < ApplicationController
  def hello
    @time = Time.now
  end

  def goodbye
  end
end

and modify the view to display the variable set for it by the controller:

<h1>Hello from Rails!</h1>
<p>
  It is now <%= @time %>
</p>

The time is data, so it is supplied to the view by the controller. The book forewarns us we’ll see a lot more of this once we introduce models. It goes on to explain the step-by-step process of what the server goes through when responding to a request, at a very high level. We then customize our goodbye page, but you can checkout the git repo if you want to see that or the results of completing either of the chapter’s two exercises. The one remaining item of interest it does in the app is add a link from the Hello page to the Goodbye page and vice versa. It does this using built in helper methods rather than hardcoding URL’s. The new hello.html.erb looks like:

<h1>Hello from Rails!</h1>
<p>
  It is now <%= @time %>
</p>
<p>
  Time to say
  <%= link_to "Goodbye", say_goodbye_path %>!
</p>

The first parameter in the call to link_to() is the text to be displayed in the hyperlink, and the next parameter tells Rails to generate the link to the goodbye action of the say controller.

Finally in this chapter, they display what happens when things break. As the authors put it “the true test of the developer friendliness of a framework is how it responds when things go wrong.” First, they ask what would happen if we misspelled Time.now as Time.know in our controller. Rails not only tells you the exact spot of the error, it also asks if you meant to type “now” and offers an interactive debugging console:

rails error page

And before you start worrying, the web console is only shown if your on the same machine as the web server and running in development mode, so there shouldn’t be any chance of anyone getting into it in production unless you specifically whitelist more ips and run the server in development mode. Likewise, if you attempt to go to http://localhost:3000/say/h3llo instead of /say/hello, you get:

rails error page

It gives you a list of possible routes along with what controller and action they are associated with and a helpful search box to trim it down.

Altogether, the app presented here is totally trivial, but in this chapter they did manage to cover:

  • How to create a new Rails application and how to create a new controller in that application
  • How to create dynamic content in the controller and display it via the view
  • How to link pages together
  • How to debug problems in code or the URL

Looks like the next chapter covers a bit of MVC theory, and chapter 4 is a Rails review. I’ll probably comment on both in one quick post. Then in Chapter 5, we dig into building a bigger application.