1.5. Creating a ControllerYou've seen that Rails organizes applications into pieces with a model, view, and controller. We'll start with the controller. Use the generate script (see the sidebar "script/generate") to create a controller. We'll specify the type of object to create first and then the name of the new controller. Type: > ruby script/generate controller Greeting exists app/controllers / exists app/helpers/ create app/views/greeting exists test/functional/ create app/controllers/greeting_controller.rb create test/functional/greeting_controller_test.rb create app/helpers/greeting_helper.rb You might not have expected to see so much activity. Rails created your expected controller-- greeting_controller.rb . But you also got a few other files as well:
Ruby developers created Rails to solve their own problems before generalizing and releasing the tool to solve your problems too. You're seeing an example of excellent experience-based design. Early Rails users noticed that right after creating a controller, they usually needed additional layers of the application, and so they modified the controller generator to save themselves a few keystrokes. Rails inventors eat their own dog food. 1.5.1. Running the ControllerLet's run the application; point your browser to http://127.0.0.1:3000/greeting. You'll get an error message telling you that index is an unknown action. Let's find out why. Edit the new controller at the path app/controller/greeting_controller.rb : class GreetingController < ApplicationController end
You haven't told Rails to do anything yet, so getting some kind of error seems logical. Still, you'll need a little more background before you can fix that problem. Figure 1-2 shows how Rails controllers work. Figure 1-2. Rails' model-view-controller flowRails uses the Action Pack framework to manage controllers. Web browsers communicate with servers by sending requests over the HTTP protocol. For our greeting application, the request was simply to load a URL. The first part of a URL identifies a machine, and the second part identifies a web resource. In the Action Pack, the resource has at least three parts : a controller, some action to perform on a controller, and an identifier of a resource. Actions map directly onto controller methods . For example, for this URL: http://www.spatulas.com/shopping_cart/total/45 http://www.spatulas.com/ identifies the web server, shopping_cart identifies the controller, total identifies the action, and 45 identifies a resourceprobably a cart. The web server routes incoming requests to a Ruby script in the Rails framework called the dispatcher . Rails has one dispatcher per web server. Next, the Rails dispatcher parses the URL and invokes the appropriate action on the appropriate controller. The controller action may then call the model and ultimately invokes a view. By default, if you call a controller without specifying an action, Rails calls the index action. Now, the error makes more sense. When we specified the URL app/controller/greeting , we supplied a controller without an action, so Rails defaulted to a nonexistent index action. You can fix the problem by adding a method called index to GreetingController . Let's keep things simple by making the index method print out HTML directly, as shown in Example 1-1. Example 1-1. Rails controller displaying a greeting
Save your code and reload your browseryou'll get the web page in Figure 1-3. Even though you changed some code, you didn't have to restart the server, redeploy your application, or do anything but reload your browser. This quick turnaround time, called a rapid feedback loop , is a hallmark of Ruby and Rails. Often, new Rails developers point to the rapid feedback loop as the feature that affected their productivity more than anything else. Figure 1-3. Rendering text from a controller |