

Action Controller Overview

In this guide you will learn how controllers work and how they fit into the request cycle in your application. After reading this guide, you will be able to:

1 What Does a Controller Do?


For most conventional RESTful applications, the controller will receive the request (this is invisible to you as the developer), fetch or save data from a model and use a view to create HTML output. If your controller needs to do things a little differently, that’s not a problem, this is just the most common way for a controller to work.



2 Methods and Actions


class ClientsController < ApplicationController
  def new


def new
  @client =

The Layouts & Rendering Guide explains this in more detail.

ApplicationController inherits from ActionController::Base, which defines a number of helpful methods. This guide will cover some of these, but if you’re curious to see what’s in there, you can see all of them in the API documentation or in the source itself.


3 Parameters

You will probably want to access data sent in by the user or other parameters in your controller actions. There are two kinds of parameters possible in a web application. The first are parameters that are sent as part of the URL, called query string parameters. The query string is everything after “?” in the URL. The second type of parameter is usually referred to as POST data. This information usually comes from an HTML form which has been filled in by the user. It’s called POST data because it can only be sent as part of an HTTP POST request. Rails does not make any distinction between query string parameters and POST parameters, and both are available in the params hash in your controller:

class ClientsController < ActionController::Base
  # This action uses query string parameters because it gets run
  # this action would look like this in order to list activated
  # clients: /clients?status=activated
  def index
    if params[:status] == "activated"
      @clients = Client.activated
      @clients = Client.unactivated

  # This action uses POST parameters. They are most likely coming
  # sent as part of the request body.
  def create
    @client =[:client])
      redirect_to @client
      # This line overrides the default rendering behavior, which
      # would have been to render the "create" view.
      render :action => "new"

3.1 Hash and Array Parameters

The params hash is not limited to one-dimensional keys and values. It can contain arrays and (nested) hashes. To send an array of values, append an empty pair of square brackets “[]” to the key name:


The actual URL in this example will be encoded as “/clients?ids%5b%5d=1&ids%5b%5d=2&ids%5b%5d=3” as “[” and “]” are not allowed in URLs. Most of the time you don’t have to worry about this because the browser will take care of it for you, and Rails will decode it back when it receives it, but if you ever find yourself having to send those requests to the server manually you have to keep this in mind.




When this form is submitted, the value of params[:client] will be {"name" => “Acme”, “phone” => “12345”, “address” => {"postcode" => “12345”, “city” => “Carrot City”}}. Note the nested hash in params[:client][:address].

Note that the params hash is actually an instance of HashWithIndifferentAccess from Active Support, which acts like a hash that lets you use symbols and strings interchangeably as keys.

3.2 JSON/XML parameters

If you’re writing a web service application, you might find yourself more comfortable on accepting parameters in JSON or XML format. Rails will automatically convert your parameters into params hash, which you’ll be able to access like you would normally do with form data.

So for example, if you are sending this JSON parameter:


You’ll get params[:company] as { :name => “acme”, “address” => “123 Carrot Street” }.

Also, if you’ve turned on config.wrap_parameters in your initializer or calling wrap_parameters in your controller, you can safely omit the root element in the JSON/XML parameter. The parameters will be cloned and wrapped in the key according to your controller’s name by default. So the above parameter can be written as:


And assume that you’re sending the data to CompaniesController, it would then be wrapped in :company key like this:

{ :name => "acme", :address => "123 Carrot Street", :company => { :name => "acme", :address => "123 Carrot Street" }}


3.3 Routing Parameters


match '/clients/:status' => 'clients#index', :foo => "bar"

In this case, when a user opens the URL /clients/active, params[:status] will be set to “active”. When this route is used, params[:foo] will also be set to “bar” just like it was passed in the query string. In the same way params[:action] will contain “index”.

3.4 default_url_options


class ApplicationController < ActionController::Base
  def default_url_options
    {:locale => I18n.locale}

These options will be used as a starting point when generating URLs, so it’s possible they’ll be overridden by the options passed in url_for calls.


4 Session


  • ActionDispatch::Session::CookieStore – Stores everything on the client.
  • ActiveRecord::SessionStore – Stores the data in a database using Active Record.
  • ActionDispatch::Session::CacheStore – Stores the data in the Rails cache.
  • ActionDispatch::Session::MemCacheStore – Stores the data in a memcached cluster (this is a legacy implementation; consider using CacheStore instead).





Read more about session storage in the Security Guide.


# which shouldn't be used to store highly confidential information
# (create the session table with "script/rails g session_migration")
# YourApp::Application.config.session_store :active_record_store



YourApp::Application.config.session_store :cookie_store, :key => '_your_app_session'



YourApp::Application.config.session_store :cookie_store, :key => '_your_app_session', :domain => ""



# Your secret key for verifying the integrity of signed cookies.
# no regular words or you'll be exposed to dictionary attacks.
YourApp::Application.config.secret_token = '49d3f3de9ed86c74b94ad6bd0...'


4.1 Accessing the Session


Sessions are lazily loaded. If you don’t access sessions in your action’s code, they will not be loaded. Hence you will never need to disable sessions, just not accessing them will do the job.


class ApplicationController < ActionController::Base


  # a Rails application; logging in sets the session value and
  # logging out removes it.
  def current_user
    @_current_user ||= session[:current_user_id] &&


class LoginsController < ApplicationController
  def create
      # subsequent requests
      session[:current_user_id] =
      redirect_to root_url


class LoginsController < ApplicationController
  def destroy
    # Remove the user id from the session
    @_current_user = session[:current_user_id] = nil
    redirect_to root_url

To reset the entire session, use reset_session.

4.2 The Flash

The flash is a special part of the session which is cleared with each request. This means that values stored there will only be available in the next request, which is useful for storing error messages etc. It is accessed in much the same way as the session, like a hash. Let’s use the act of logging out as an example. The controller can send a message which will be displayed to the user on the next request:

class LoginsController < ApplicationController
  def destroy
    session[:current_user_id] = nil
    flash[:notice] = "You have successfully logged out"
    redirect_to root_url

Note it is also possible to assign a flash message as part of the redirection.

redirect_to root_url, :notice => "You have successfully logged out"

The destroy action redirects to the application’s root_url, where the message will be displayed. Note that it’s entirely up to the next action to decide what, if anything, it will do with what the previous action put in the flash. It’s conventional to display eventual errors or notices from the flash in the application’s layout:

  <!-- <head/> -->
    <% if flash[:notice] %>
    <% end %>
    <% if flash[:error] %>
      <p class="error"><%= flash[:error] %></p>
    <% end %>
    <!-- more content -->

This way, if an action sets an error or a notice message, the layout will display it automatically.


class MainController < ApplicationController
  # Let's say this action corresponds to root_url, but you want
  # all requests here to be redirected to UsersController#index.
  # would normally be lost when another redirect happens, but you
  def index
    # Will persist all flash values.

    # flash.keep(:notice)
    redirect_to users_url


class ClientsController < ApplicationController
  def create
    @client =[:client])
      # ...
    else[:error] = "Could not save client"
      render :action => "new"

5 Cookies


class CommentsController < ApplicationController
  def new
    @comment = => cookies[:commenter_name])

  def create
    @comment =[:comment])
      if params[:remember_name]
        # Remember the commenter's name.
        cookies[:commenter_name] =
        # Delete cookie for the commenter's name cookie, if any.
      redirect_to @comment.article
      render :action => "new"


6 Rendering xml and json data

ActionController makes it extremely easy to render xml or json data. If you generate a controller using scaffold then your controller would look something like this.

class UsersController < ApplicationController
  def index
    @users = User.all
    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @users}
      format.json { render :json => @users}

Notice that in the above case code is render :xml => @users and not render :xml => @users.to_xml. That is because if the input is not string then rails automatically invokes to_xml .

7 Filters

Filters are methods that are run before, after or “around” a controller action.


Before filters may halt the request cycle. A common before filter is one which requires that a user is logged in for an action to be run. You can define the filter method this way:

class ApplicationController < ActionController::Base
  before_filter :require_login


  def require_login
    unless logged_in?
      redirect_to new_login_url # halts request cycle

  # The logged_in? method simply returns true if the user is logged
  # in and false otherwise. It does this by "booleanizing" the
  # current_user method we created previously using a double ! operator.
  # Note that this is not common in Ruby and is discouraged unless you
  # really mean to convert something into true or false.
  def logged_in?

The method simply stores an error message in the flash and redirects to the login form if the user is not logged in. If a before filter renders or redirects, the action will not run. If there are additional filters scheduled to run after that filter they are also cancelled.

In this example the filter is added to ApplicationController and thus all controllers in the application inherit it. This will make everything in the application require the user to be logged in in order to use it. For obvious reasons (the user wouldn’t be able to log in in the first place!), not all controllers or actions should require this. You can prevent this filter from running before particular actions with skip_before_filter:

class LoginsController < ApplicationController
  skip_before_filter :require_login, :only => [:new, :create]


7.1 After Filters and Around Filters

In addition to before filters, you can also run filters after an action has been executed, or both before and after.

After filters are similar to before filters, but because the action has already been run they have access to the response data that’s about to be sent to the client. Obviously, after filters cannot stop the action from running.



class ChangesController < ActionController::Base
  around_filter :wrap_in_transaction, :only => :show


  def wrap_in_transaction
    ActiveRecord::Base.transaction do
        raise ActiveRecord::Rollback

Note that an around filter wraps also rendering. In particular, if in the example above the view itself reads from the database via a scope or whatever, it will do so within the transaction and thus present the data to preview.

They can choose not to yield and build the response themselves, in which case the action is not run.

7.2 Other Ways to Use Filters

While the most common way to use filters is by creating private methods and using *_filter to add them, there are two other ways to do the same thing.

The first is to use a block directly with the *_filter methods. The block receives the controller as an argument, and the require_login filter from above could be rewritten to use a block:

class ApplicationController < ActionController::Base
  before_filter do |controller|
    redirect_to new_login_url unless controller.send(:logged_in?)



class ApplicationController < ActionController::Base
  before_filter LoginFilter

class LoginFilter
  def self.filter(controller)
    unless controller.send(:logged_in?)
      controller.redirect_to controller.new_login_url

Again, this is not an ideal example for this filter, because it’s not run in the scope of the controller but gets the controller passed as an argument. The filter class has a class method filter which gets run before or after the action, depending on if it’s a before or after filter. Classes used as around filters can also use the same filter method, which will get run in the same way. The method must yield to execute the action. Alternatively, it can have both a before and an after method that are run before and after the action.

8 Request Forgery Protection


The first step to avoid this is to make sure all “destructive” actions (create, update and destroy) can only be accessed with non-GET requests. If you’re following RESTful conventions you’re already doing this. However, a malicious site can still send a non-GET request to your site quite easily, and that’s where the request forgery protection comes in. As the name says, it protects from forged requests.


If you generate a form like this:

<%= form_for @user do |f| %>
  <%= f.text_field :username %>
  <%= f.text_field :password %>
<% end %>


<input type="hidden"
<!-- fields -->

Rails adds this token to every form that’s generated using the form helpers, so most of the time you don’t have to worry about it. If you’re writing a form manually or need to add the token for another reason, it’s available through the method form_authenticity_token:

The form_authenticity_token generates a valid authentication token. That’s useful in places where Rails does not add it automatically, like in custom Ajax calls.


9 The Request and Response Objects


9.1 The request Object


Property of request Purpose
host The hostname used for this request.
domain(n=2) The hostname’s first n segments, starting from the right (the TLD).
format The content type requested by the client.
method The HTTP method used for the request.
get?, post?, put?, delete?, head? Returns true if the HTTP method is GET/POST/PUT/DELETE/HEAD.
headers Returns a hash containing the headers associated with the request.
port The port number (integer) used for the request.
protocol Returns a string containing the protocol used plus “://”, for example “http://”.
query_string The query string part of the URL, i.e., everything after “?”.
remote_ip The IP address of the client.
url The entire URL used for the request.
9.1.1 path_parameters, query_parameters, and request_parameters


9.2 The response Object

The response object is not usually used directly, but is built up during the execution of the action and rendering of the data that is being sent back to the user, but sometimes – like in an after filter – it can be useful to access the response directly. Some of these accessor methods also have setters, allowing you to change their values.

Property of response Purpose
content_type The content type of the response.
charset The character set being used for the response. Default is “utf-8”.
headers Headers used for the response.
9.2.1 Setting Custom Headers



10 HTTP Authentications

Rails comes with two built-in HTTP authentication mechanisms:

  • Basic Authentication
  • Digest Authentication

10.1 HTTP Basic Authentication

HTTP basic authentication is an authentication scheme that is supported by the majority of browsers and other HTTP clients. As an example, consider an administration section which will only be available by entering a username and a password into the browser’s HTTP basic dialog window. Using the built-in authentication is quite easy and only requires you to use one method, http_basic_authenticate_with.

class AdminController < ApplicationController
  http_basic_authenticate_with :name => "humbaba", :password => "5baa61e4"


10.2 HTTP Digest Authentication


class AdminController < ApplicationController
  USERS = { "lifo" => "world" }

  before_filter :authenticate


  def authenticate
    authenticate_or_request_with_http_digest do |username|

As seen in the example above, the authenticate_or_request_with_http_digest block takes only one argument – the username. And the block returns the password. Returning false or nil from the authenticate_or_request_with_http_digest will cause authentication failure.

11 Streaming and File Downloads


To stream data to the client, use send_data:

require "prawn"
class ClientsController < ApplicationController
  # Generates a PDF document with information on the client and
  def download_pdf
    client = Client.find(params[:id])
    send_data generate_pdf(client),
              :filename => "#{}.pdf",
              :type => "application/pdf"


  def generate_pdf(client) do
      text, :align => :center
      text "Address: #{client.address}"
      text "Email: #{}"


11.1 Sending Files


class ClientsController < ApplicationController
  def download_pdf
    client = Client.find(params[:id])
              :filename => "#{}.pdf",
              :type => "application/pdf")





11.2 RESTful Downloads

While send_data works just fine, if you are creating a RESTful application having separate actions for file downloads is usually not necessary. In REST terminology, the PDF file from the example above can be considered just another representation of the client resource. Rails provides an easy and quite sleek way of doing “RESTful downloads”. Here’s how you can rewrite the example so that the PDF download is a part of the show action, without any streaming:

class ClientsController < ApplicationController
  def show
    @client = Client.find(params[:id])

    respond_to do |format|
      format.pdf { render :pdf => generate_pdf(@client) }


Mime::Type.register "application/pdf", :pdf


Now the user can request to get a PDF version of a client just by adding “.pdf” to the URL:

GET /clients/1.pdf

12 Parameter Filtering

Rails keeps a log file for each environment in the log folder. These are extremely useful when debugging what’s actually going on in your application, but in a live application you may not want every bit of information to be stored in the log file. You can filter certain request parameters from your log files by appending them to config.filter_parameters in the application configuration. These parameters will be marked [FILTERED] in the log.

config.filter_parameters << :password

13 Rescue


Rails’ default exception handling displays a “500 Server Error” message for all exceptions. If the request was made locally, a nice traceback and some added information gets displayed so you can figure out what went wrong and deal with it. If the request was remote Rails will just display a simple “500 Server Error” message to the user, or a “404 Not Found” if there was a routing error or a record could not be found. Sometimes you might want to customize how these errors are caught and how they’re displayed to the user. There are several levels of exception handling available in a Rails application:

13.1 The Default 500 and 404 Templates


13.2 rescue_from




class ApplicationController < ActionController::Base
  rescue_from ActiveRecord::RecordNotFound, :with => :record_not_found


  def record_not_found
    render :text => "404 Not Found", :status => 404

Of course, this example is anything but elaborate and doesn’t improve on the default exception handling at all, but once you can catch all those exceptions you’re free to do whatever you want with them. For example, you could create custom exception classes that will be thrown when a user doesn’t have access to a certain section of your application:

class ApplicationController < ActionController::Base
  rescue_from User::NotAuthorized, :with => :user_not_authorized


  def user_not_authorized
    redirect_to :back

class ClientsController < ApplicationController
  before_filter :check_authorization

  def edit
    @client = Client.find(params[:id])


  def check_authorization
    raise User::NotAuthorized unless current_user.admin?

Certain exceptions are only rescuable from the ApplicationController class, as they are raised before the controller gets initialized and the action gets executed. See Pratik Naik’s article on the subject for more information.

14 Force HTTPS protocol

Sometime you might want to force a particular controller to only be accessible via an HTTPS protocol for security reasons. Since Rails 3.1 you can now use force_ssl method in your controller to enforce that:

class DinnerController

Just like the filter, you could also passing :only and :except to enforce the secure connection only to specific actions.

class DinnerController
  force_ssl :only => :cheeseburger
  # or
  force_ssl :except => :cheeseburger

Please note that if you found yourself adding force_ssl to many controllers, you may found yourself wanting to force the whole application to use HTTPS instead. In that case, you can set the config.force_ssl in your environment file.


You're encouraged to help improve the quality of this guide.



