Ruby for Programmers – Part 12: Totally Metal

Earlier, we briefly went over the controller as a way to store the methods of routes, but there’s way more to it then returning a bunch of status codes and headers. So now we’re going to add another piece of the pie, the ActionController, which is actually three different classes in increasing complexity, the AbstractController, the Metal, and the ActionController.

The AbstractController::Base just contains a base set of functions and modules that help out. Normally one wouldn’t make an AbstractController::Base, but this is just for show. So here’s our AbstractController:

So that doesn’t look much different then before. We still have to make our own self.action method. But we now have access to a few cool built-ins, the most important of which is the callback:

What it does, is allows a function to operate before all functions. On both pages, @hi is set. This is useful for tons of things like session management, page view counts, etc.

But, we still have to do that goofy array, so let’s get rid of it… with Metal. \__/

The ActionController Metal the base class that simply does what we already do with the array format and the action handle, but adds some sprinkles to make it look better. It’s only 235 lines long and doesn’t include much fluff.

So here’s our totally Metal controller:

All the Metal really does is abstract out the env and the array, and also by default sets the content-type to ‘text/html’. Which is still a bonus because this controller is now starting to look good. It’s got some basic includes at the top, and just responds with basic text. At this point, all we did was abstract out the basics even more. Outside of including modules (like the Callback), the Metal is just a fancier version of our starting basic controller that’s not part of any class.

The Metal alone is perfectly serviceable, and some people prefer to use it. History lesson: the Rails Metal comes from the merge of Rails and Merb, where Merb was a from-the-ground-up system with plugins like I’m showing here.

Since we’re (mostly) done with abstracting out how to build a webpage, the next few segments will focus on the ‘batteries included’ part of Rails.

A couple of extra notes about callbacks, first you can limit the callback, or even skip the callback, to specific functions. Just add the array of the functions:

Skipping filters is useful for hierarchical class inheritance.

Also, when a callback returns with a response_body (or renders or redirects as we’ll see later), it skips the rest of the call stream. For example this:

Would always render “mystery callback” onto a page and never even run the #index or #show functions. This is another useful thing to be mindful of, and yet another powerful feature. For example, if you want to enforce a user login, then all you have to do is check if the user is logged in, and if not, redirect them to the login page. It will both not run the code they cannot use (since they are not logged in) and it will redirect them to a page where they can login. Useful!