3.4. Redirects

The name says it all, really: redirects are commands that you can use within the controller to skip, i.e. redirect, to other to other web pages.

Note

A redirect returns to the browser the response "302 Moved" with the new target.
Let's create a new Rails project for a suitable example:
$ rails new redirect_example

[...]

$ cd redirect_example 
$ 
Before we can redirect, we need a controller with at least two different methods. Off we go then:
$ rails generate controller Game ping pong
      create  app/controllers/game_controller.rb
       route  get "game/pong"
       route  get "game/ping"
      invoke  erb
      create    app/views/game
      create    app/views/game/ping.html.erb
      create    app/views/game/pong.html.erb
      invoke  test_unit
      create    test/functional/game_controller_test.rb
      invoke  helper
      create    app/helpers/game_helper.rb
      invoke    test_unit
      create      test/unit/helpers/game_helper_test.rb
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/game.js.coffee
      invoke    scss
      create      app/assets/stylesheets/game.css.scss
$
The new rails webapplication has two possible routes:
$ rake routes
game_ping GET /game/ping(.:format) game#ping
game_pong GET /game/pong(.:format) game#pong
$
The controller app/controllers/game_controller.rb has the following content:
class GameController < ApplicationController
  def ping
  end

  def pong
  end
end
Now for the redirect: how can we achieve that we get immediately redirected to the method pong when we go to http://0.0.0.0:3000/game/ping? Easy, you will say, we just change the route in config/routes.rb. And you are right. So we don't necessarily need a redirect. But if we want to process something else in the method ping before redirecting, then this is only possible by using a redirect_to in the controller app/controllers/game_controller.rb:
class GameController < ApplicationController
  def ping
   logger.info '+++  Example  +++'
   redirect_to game_pong_path
  end

  def pong
  end
end
But what is game_pong_path? Let's have a look a the routes generated for this Rails application:
$ rake routes
game_ping GET /game/ping(.:format) game#ping
game_pong GET /game/pong(.:format) game#pong
$

Note

As you can see, the route to the action ping of the controller GameController now gets the name game_ping (see beginning of the line). We could also write the redirect like this:
redirect_to :action => 'pong'
I will explain the details and the individual options of the redirect later in the context of each specific case. For now, you just need to know that you can redirect not just to another method, but also to another controller or an entirely different web page.
When we try to go to http://0.0.0.0:3000/game/ping we are automatically redirected to http://0.0.0.0:3000/game/pong and in the log output we see this:
Started GET "/game/ping" for 127.0.0.1 at 2012-11-13 20:35:44 +0100
Connecting to database specified by database.yml
Processing by GameController#ping as HTML
+++  Example  +++
Redirected to http://0.0.0.0:3000/game/pong
Completed 302 Found in 1ms (ActiveRecord: 0.0ms)


Started GET "/game/pong" for 127.0.0.1 at 2012-11-13 20:35:44 +0100
Processing by GameController#pong as HTML
  Rendered game/pong.html.erb within layouts/application (2.4ms)
Completed 200 OK in 35ms (Views: 34.5ms | ActiveRecord: 0.0ms)

Updates about this book will be published on my Twitter feed.