When I started writing part II, I started writing about models. As I got a little further along, I realized that it would be more helpful to provide an overview of the controller, which provides the data that goes into your web page, before I showed you how to get the data out of the database. My hope is that you’ll read this thinking of how you want the data provided, which adds context to part III on models.
Controllers are Where the Work Gets Done
Have you ever worked with one of those people who knows exactly where to go to get everything he needs. Can delegate his tasks effortlessly, and then pull it all together in the end. That guy would be our controller. When your website’s user browses to the page, the Rails engine picks up the request and decides which controller to send it to. More specifically, it decides which method in the controller to send it to. The methods on the controller are referred to as actions.
Examples and code snippets seem to be most effective when I read tutorials, so I’ll start out with a basic controller action for a page that lists all users in the application.
class UserController < ApplicationController def list @users = User.find(:all) end end
Don’t worry too much about the User.find call. We’ll cover that with models in part III. The important part here is that they are stored in the instance variable @users. @users in this instance contains an array of all of the users in the system. In our view, covered in part IV, we can iterate over the array and display all of the users.
You can also make other find calls to the model to get a specific user or group of users which you can display on your pages.
Besides loading variables for your views, controller actions can be used to execute other ruby code. For example, this code will accept form parameters and create a new post object.
class PostController < ApplicationController def create @post = Post.create(params[:post]) end end
The thing to note in this code snippet is the ‘params’ method which provides a Ruby hash containing all HTTP POST and GET parameters. In this case it contains a hash key called :post that references another hash with the attributes for our new post object.
Controllers are not limited to database transactions. You can operate on session variables, cookie variables, or even parameters.
class SessionCookieMathController < ApplicationController def increment_session_count session[:count] += 1 end def increment_cookie_count cookies[:count] += 1 end def increment_params_count params[:count] += 1 end end
Controller Rendering Formats
Controllers are capable of rendering data in several different formats. For this tutorial, we’ll cover strings and views.
Rendering is controlled by the ‘render’ method. Here are some examples of strings, views, and no render call.
class RenderExampleController < ApplicationController def string render :text => "This text will be rendered as the HTTP response body." end def no_render @variable = "Something" # This will render the view at app/views/render_example/no_render.html.erb end def view @variable = "Something render :action => "someview" end end
Let’s start at the first action and work our way down. The first action has the “render :text” call. The text key tells render that the string should be inserted into the response body. If you had a “render :text => ‘<html><body style=”background-color: red”> <body></html>’” call, you’d wind up with a web page with a red body.
The second action doesn’t have a render call. In that case, looks in app/views/render_example/ for a file called no_render.
.erb.
Finally, the last “render :action” call renders the view in app/views/render_example/ that matches the string assigned to :action.
Views typically are stored in files called app/views/ named .
.erb. The most common formats are html and xml, which render to .html pages or .xml pages respectively.
Redirecting in Controllers
Finally, instead of rendering, you can redirect to a new page. You can do that with a ‘redirect_to’ call. Here’s a quick example.
class RedirectingController < ApplicationController def go_to_google redirect_to "http://www.google.com" end def go_to_the_homepage redirect_to "/" end def go_to_login_page redirect_to :controller => "user", :action => "login" end end
Again, we have three simple examples to go over. In the first example, it redirects to “www.google.com.” Your redirect string must start with “http://” in order for this to work. If you don’t, it’ll try going to a local path.
In the second example, the “/” is interpreted as a relative path. In this case, it goes to the root path.
In the third example, it translates the controller and action into a standard path formation of /controller/action. So that redirect would take you to “/user/login.” You can add more parameters to the redirect by specifying the key as a string or symbol (:symbol) and the value as a string.
There are other advanced functions you can use in your controllers that won’t be covered here, but keep an eye out for coverage of filters and forgery protection.