The core of any Ruby on Rails web application is the data to be accessed. Instead of giving you a thin layer over the HTTP server and saying "have at it!" and forcing you to invent your own (possibly wrong, or at least inconsistent) interfaces to this data, Ruby on Rails has a sane default that you probably want for 99% of all of your data: resources. But before you can understand resources, you need to understand routing and CRUD.
What connects an HTTP query to a specific URL to an action an a controller? This is the job of the Ruby on Rails router, it correlates URLs with actions and makes sure everything goes to the right place. There are a lot of things you can do with a the router, but at the very least you'll need to tell it about resources. In Ruby on Rails, a resource is much less of a thing, and much more of an interface to a thing. The resource is not the thing itself, or the data that it's accessing, but it's the set of URLs that get mapped to the thing.
To configure the Ruby on Rails router, open up config/routes.rb. By default, you'll see a rather empty file with a single block and nothing but comments. These comments are rather useful, as you'll most often be adding simple things to this file and if you're anything like me, always forget how to do anything differently in this file. So read through these comments, and keep them if you wish.
This file is a list of rules that match URLs. Ruby on Rails will follow the first rule that matches the URL, anything after that will be ignored. You can start by adding a root route, or what controller and action will run when the root URL is accessed. Right now it goes to a static HTML page, so let's change that to our Hello controller, with the world action. At the top of the routes.rb file (but still inside the block), add the following line. After you're done doing that, remove the public/index.html file, as these static files will override any routes in place.
FirstRailsProject::Application.routes.draw do # This line was added when the controller was generated get "hello/world" # Add this line manually root :to => 'hello#world' end
Now, opening up http://localhost:3000/ in your web browser will go right to your "hello world" action. Note the "hello#world" convention used to denote a controller and action, this will be used in a number of places.
You can add routes manually by using the get method. As in the code above, the get "hello/world" URL will automatically map to the hello#world action. So any HTTP GET request to hello/world will go to the hello world action. Without this route, this action is completely cut off from the outside world, there is no way to access it. So if you were to add another action to the controller, you'd have to hook it up using a route.
So let's do that, let's add another action to the Hello controller. We originally created the controller using a generator, but that's not necessary here. To add a new action, all we need to do is add a new (even empty) method to the Hello class and add the corresponding view. So let's add an action to greet our friend Steve. First, create the action in app/controllers/hello_controller.rb.
class HelloController < ApplicationController
@message = "<p>Hello world!</p>"
The method is empty, but that's OK. It will just automatically generate the associated view. So let's add that as app/views/hello/steve.html.erb. This can just be an empty file, but we'll create the file and add a message to Steve.
<p>I thought you'd like this site, so I left you a message.</p>
Everything is looking good so far, but if you go to http://localhost:3000/hello/steve, you get a routing error. We haven't made the route yet, so go open up config/routes.rb again and we'll add this. Also, if you haven't been able to tell by now, having an editor that allows you to switch between files throughout the hierarchy, or at the very least an editor that lets you have multiple tabs open, is essential for working with Rails.
FirstRailsProject::Application.routes.draw do get "hello/world" # We'll add this line to tell Rails about the new action get "hello/steve" root :to => 'hello#world' end
But what if you want the URL to be something different? What if you want to greet Steve using the hello/friend URL, but still have the action be called hello#steve? Take a look at the root method call at the bottom, we'll use something similar. Instead of using a single string parameter, we'll pass the same hash parameter instead.
FirstRailsProject::Application.routes.draw do get "hello/world" # Use a hash parameter instead get "hello/friend" => 'hello#steve' root :to => 'hello#world' end
And there you have it. Now that you know how, basically, how the Ruby on Rails router works, you can add any routes and hook them up to any controllers and actions that you wish. But don't think everything in Rails is so tedious, generally you don't manually tell the Ruby on Rails router about every single action you have. Normally, you'll simply tell it of a resource, and it'll hook up multiple actions automatically. Since most things you'll do will follow the resource pattern, manually defining routes is the exception, not the rule.