Ruby for Programmers – Part 10: Actionpacked Routing!

So as we saw in the last part, having different pages might end up being a slight pain, so let’s add some routing. First we’re going to need the actionpack gem, so lets add that to our Gemfile:

Note that we’re going to be using the latest beta version because by the time this is done, the new version will be out. 😛

Run bundle install to install your new gem.

Woah, that’s a lot of dependencies! We’ll eventually get to them as needed. But for now, we’re just going to include the routing part.

The config.ru allows the use of Middleware, or something that’s run before your app. So if you wish to use a something that automates something before every page call, such as routing, then you can make a Middleware. For a simple example, look at what happens when there’s an error in your code:

Load that in your browser via bundle exec rackup. It will show the default Rack error page. But what if you want a fancier page? There’s a middleware for that: ActionDispatch::ShowExceptions . It will allow us to show webpages to status errors so that the end-user doesn’t see code errors. It’s real simple to add, first add the files to a new folder “public”, and individual status codes like so:

Screen Shot 2014-01-05 at 6.03.08 PM

You can get the HTML for those pages in the public example on Github.

Why is the folder called “public”? Because I said so. (It’s a Rails convention actually.)

Then add the following to your config.ru:

The new line means to use the middleware ActionDispatch::ShowExceptions, with the argument of “ActionDispatch::PublicExceptions.new(“public/”)”. In this case, ActionDispatch::ShowExceptions requires a secondary middleware to route to actually show the exception. The “public/” of course means to look for any files in our newly created public folder.

Then load your front page. It should now have a prettier error page:

Screen Shot 2014-01-05 at 6.05.41 PM

It’s the little things that count.

So lets add some routing, so here’s our updated config.ru file:

So let’s go over what we did. First, we created a new RouteSet, which is fine, and then started to draw some routes. Notice how the routes mention a “mainpage#index” or “mainpage#show”? It means that to route that to a MainpageController#index or MainpageController#show action. Why does it add Controller to the class name? Because I say so.

On the MainpageController is a self.action handler to handle the route internals by creating a new instance. And the individual methods now look like before with the status, header, body like in the other example.

Towards the end we add ActionDispatch::DebugExceptions to show the errors in the log in our terminal, because errors are now hidden from the browser. And finally, our app is no longer a function but rather the routes we created (which will forward to it’s respective controller).

Anyway, the routes are exactly like Rails routes, so a better documentation was written in the Rails Guide. There is some fancy pants stuff other than generating each individual route, like “namespace” which allows you to create namespaced controllers (like Admin::PostController for an admin interface), “resources” which creates the standard routes for an object (index, show, new, edit, create, update, destroy), and constraints by regex, subdomain, and more.

We’ll be going over the part of routes we’ll be adding as we add them. This just shows how routes fits in the whole scheme.

Download the working example code here: https://github.com/ROFISH/ruby_for_programmers/tree/master/10