A controller pulls the strings on the marionette that is your web application. The web server receives the request and once it decides which controller should handle the request, hands over control to that controller. The controller will typically use the model to fetch data and hand that data over to a view, which will produce the HTML output. So before we can dig into models and views, we need to understand a bit about how controllers fit in.
A controller itself is just a Ruby class, a child class of ActionController::Base. Inside this controller class are methods, each public method being an action for that controller. A controller can represent an activity for the site, for example the BlogController controller class is responsible for fetching, displaying, creating and editing blog posts. Some of the actions for such a controller may be view to view a blog post, or create to insert a new blog post into the database. At its most basic level, a controller is a collection of related actions. Each action maps (typically) to a single URL.
Generating a Controller
We've used the rails command line command before, to generate the project itself or to start the server. Now we're going to use the rails command to generate a new controller. Rails generators give you stub files, in this case a new controller and some view files will be created for you. These will be mostly empty, but they save you from having to remember which class the controller needs to inherit from, or where your views go. You just run the generator and get some stub files and go from there.
We're going to generate a simple controller, its name is hello and it has a single action we're interested in, world. To generate a controller, run the command rails generate controller hello world. If we wanted to generate a second action along with world, like steve for example, we would append that action name to the list of actions at the end of the command, like rails generate controller hello world steve. But right now we only need one action.
Ruby on Rails gives you a list of the files that it created, as well as some other tasks. Of note here is the hello_controller.rb file in app/controllers and the view at app/views/hello/world.html.erb. Let's take a look at the controller.
A Bare Controller
Right now the controller it's really anything. It's an empty class with a single empty method. The class inherits from ApplicationController (which inherits from ActionController::Base) and... that's it. As you can see, this really is just a stub file, something very small meant to be built on by the programmer. Some people dislike generators, they don't like the control they sacrifice. However, these really are just stub files, using this generator will save you time.
We don't know anything about models yet, so we can't get any information from a database. But let's pretend there's a database and we're getting from info from it. Any instance variables in the controller will (as if by magic) appear as instance variables in the view. So to pass any information from the controller to the view, store it in an instance variable. Since we have no database, let's just store a message to greet the user. Such a static message would normally just be put into the view, but just pretend it's from the database. Once we've added our message, our controller looks like this.
class HelloController < ApplicationController def world @message = "Hello world!" end end
And that's it. The view doesn't need to call anything to render the HTML, Rails takes care of this for you. It will, by default, call the app/views/hello/world.html.erb view. So let's take a look at that right now. If you open this file in a text editor, you'll find a simple HTML message reminding you that the file needs to be edited. Remove this text, you don't need it. Instead, we'll replace it with the following.
<p><%= @message %></p>
That's it. First, you'll notice that there's an HTML paragraph tag. Any plain text here is automatically output. So you can start off by simply coding HTML. Whenever you need something dynamic, you can use the special ERB tags, in this case the <%= %> tag. This will evaluate the Ruby inside of it and add its string value to the output stream. In this case, the value of the @message instance variable. This is a very similar concept to PHP's tags, mixing HTML output and PHP code. However, there is a huge difference in how they're used.
You may be tempted to start putting all kinds of code into the view, don't. Mixing HTML output and code is a phenomenally bad idea, and is why most PHP code is an unmaintainable mess. So much gets lost this way, so much gets forgotten. Sure, it looks simple here, but when you views are hundreds of lines long, things are going to get messy fast. Typically you see only simple output and control statements inside of ERB tags. If you find yourself putting more code in your views than that, rethink where that code should really be going. Rails is not a fancy replacement for PHP, don't use it like one. (And as an aside, yes, PHP can be used in much more appropriate ways. But I've rarely seen it done so. PHP gets this reputation because it's really how people use it on a regular basis.)
Seeing What You've Done
Make sure your controller and view files are saved and start your Rails server with rails server. I usually have a second terminal window open and leave this running, as long as you're in development mode you should rarely, if ever, need to restart the server. Once the server is running, head on over to http://localhost:3000/hello/world to see your message. It doesn't look like much right now, but you're just beginning to orient yourself in the Rails world. Soon you'll be doing much more useful things.