Ruby for Programmers – Part 13: Revving Some Metal

Earlier we had put together a basic controller and used the Routing and Metal to render some basic pages, but since we’re going to build a simple Generic Content Manager out of this, the parameters seem important. The method in which we got that information was out of a weird quirk of information that was automatically included in the env variable that was passed around. However, there’s better ways to get this.

This isn’t a module but just automatically included in Metal that I forgot in the last part. The params variable holds all the parameters that was sent to the page, including the GET parameters, POST parameters, and parameters set by the routing:

We’re also going to add Instrumentation to the controller too. This adds tons more useful logging like page benchmarks and displays all the parameters. We also need to make a small change to our application.rb file too:

This adds the ActionController ‘railtie’, which adds useful information to the class like where the Rails log is, ability to have a config information in the config/environments folder, and the like. Don’t forget to restart your app, and you’ll notice more logging information on each page load. Cool:

What page and how long it took and what parameters, all useful information.

Rescue lets you create custom rescuables in case something goes wrong:

Pretty simple, this detects a Ruby Exception (or a subclass of Exception) and lets you render a special page from a specially defined method. In this basic example, I divided by zero accidentally in my code and rescued from that error. I should note that this is controller-wide, mostly as a last-ditch failsafe to render a decent 500 or 404 error to a user rather than the built-in HTML files.

Redirecting just creates a simple #redirect_to function that creates all the HTTP parts necessary to redirect a browser to a different page. (For the SEOers in the crowd, by default it’s a 302 Found or temporary redirect, you can set it to 301 Moved Permanently or 303 Other if you so desire.)

UrlFor is a special class that helps you create URLs from your list of routes and the current route you are using. Note in the above it says :action=>:show, :id=>”butts”, (which I’m unsure why I used the older hash rocket style, but it’s a habit). In that case, it doesn’t define a controller so the UrlFor assumes that the controller is the one that I’m on. If you use redirect_to :id=>”butts2″ while in the #show action, then it’s the same as redirect_to :controller=>”mainpage”, :action=>”show”, :id=>”butts2″ since it will assume the same route elements for the ones that are missing. Very useful for dynamic URL making.

There’s a few more modules we could add, but it’s better to look at the code and read about it since those are more “as you need it”:

  • HttpAuthentication: Allows you to set a HTTP user/password system managed by Rails (vs. being managed by the HTTP server or forwarder)
  • DataStreaming: Allows you to send files to the browser, either hosted and read directly by the forwarder, sent directly to Rack as a large string, or create dynamically generated files to force the browser to download (such as CSV files).
  • Streaming: A still-in-progress addition that allows one to render partials of a page. For example, render the top part with the CSS and Javascript, send that to the browser to chew on early, then render the rest of the page to send to the browser. Still requires lots of specialized support (ie. most middlewares and servers don’t support it), but pretty cool if it all fits together.
  • ForceSSL: A simple helper that enforces page loads over SSL and redirects if not on SSL. Useful for password pages and such.
  • Cookies: (actual documentation here), Simple cookie handling if for some reason you need tons of random cookies. (Note that we’ll be using Rail’s built-in session management to handle cookies for us, so you don’t explicitly need this. This is only if you want raw cookie access)
  • ConditionalGet: This handles HTTP caching on the user’s browser side. For example, you can tell a browser to keep a copy on a user’s computer and not download, thus saving time and bandwidth.

That’s some of the magic functions and defaults available to a Controller. As you can see, these functions mostly just get and set various HTTP information for you. Next time, we’ll be rendering. No longer will the view data be in the in controller, we’ll put that into it’s own file with it’s own logic. Yay! (Also Session Management to store data in cookies.)

As usual, working code for this part is available here: https://github.com/ROFISH/ruby_for_programmers/tree/master/13