Neu: Das englische Ruby on Rails 4.0 Buch.

3.4. Redirects (Umleitungen)

Redirects sind Befehle, mit denen Sie innerhalb des Controllers auf andere Methoden oder auch auf ganz andere Webseiten springen, also weiterleiten, können.

Anmerkung

Ein redirect gibt eine "302 Moved" response mit dem neuen Ziel an den Browser zurück.
Legen wir ein neues Rails-Projekt für ein entsprechendes Beispiel an:
MacBook:~ xyz$ rails new redirect_example
      create  
      create  README.rdoc
      create  Rakefile

[...]

Using sqlite3 (1.3.6) 
Using uglifier (1.2.4) 
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
MacBook:~ xyz$ cd redirect_example 
MacBook:redirect_example xyz$
Um zu springen, brauchen wir einen Controller mit mindestens zwei verschiedenen Methoden. Und auf gehts:
MacBook:redirect_example xyz$ 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
MacBook:redirect_example xyz$
Starten wir mal den Rails-Server und rufen mit dem Browser erst http://0.0.0.0:3000/game/ping und dann http://0.0.0.0:3000/game/pong auf:
MacBook:redirect_example xyz$ rails server
=> Booting WEBrick
=> Rails 3.2.3 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2012-04-24 13:59:36] INFO  WEBrick 1.3.1
[2012-04-24 13:59:36] INFO  ruby 1.9.3 (2012-04-20) [x86_64-darwin11.3.0]
[2012-04-24 13:59:36] INFO  WEBrick::HTTPServer#start: pid=58476 port=3000


Started GET "/game/ping" for 127.0.0.1 at 2012-04-24 14:00:01 +0200
Processing by GameController#ping as HTML
  Rendered game/ping.html.erb within layouts/application (1.9ms)
Compiled game.css  (8ms)  (pid 58476)
Compiled application.css  (18ms)  (pid 58476)
Compiled jquery.js  (3ms)  (pid 58476)
Compiled jquery_ujs.js  (0ms)  (pid 58476)
Compiled game.js  (139ms)  (pid 58476)
Compiled application.js  (173ms)  (pid 58476)
Completed 200 OK in 271ms (Views: 270.4ms | ActiveRecord: 0.0ms)

[...]

Started GET "/game/pong" for 127.0.0.1 at 2012-04-24 14:00:07 +0200
Processing by GameController#pong as HTML
  Rendered game/pong.html.erb within layouts/application (1.2ms)
Completed 200 OK in 8ms (Views: 7.8ms | ActiveRecord: 0.0ms)
Alles ganz normal. Das Projekt verfügt über zwei mögliche Routen:
MacBook:redirect_example xyz$ rake routes
game_ping GET /game/ping(.:format) game#ping
game_pong GET /game/pong(.:format) game#pong
MacBook:redirect_example xyz$
Der Controller app/controllers/game_controller.rb hat folgenden Inhalt:
MacBook:redirect_example xyz$ cat app/controllers/game_controller.rb 
class GameController < ApplicationController
  def ping
  end

  def pong
  end
end
MacBook:redirect_example xyz$
Jetzt zum Redirect: Wie können wir es erreichen, dass wir beim Aufruf von http://0.0.0.0:3000/game/ping direkt auf die Methode pong weitergeleitet werden? Einfach, werden Sie sagen, indem wir die Route in der config/routes.rb ändern. Da haben Sie Recht. Dafür brauchen wir also nicht zwingend ein Redirect. Wenn wir aber vor der Umleitung in der ping-Methode noch etwas abarbeiten wollen, dann geht das nur mit einem redirect_to im Controller app/controllers/game_controller.rb:
class GameController < ApplicationController
  def ping
   logger.info '++++++++++  Beispiel  ++++++++++'
   redirect_to game_pong_path
  end

  def pong
  end
end
Beim Aufruf von http://0.0.0.0:3000/game/ping landen wir nach dem automatischen Redirect auf http://0.0.0.0:3000/game/pong und sehen in der Log-Ausgabe die Logger-Ausgabe:
Started GET "/game/ping" for 127.0.0.1 at 2012-04-24 14:24:08 +0200
Processing by GameController#ping as HTML
++++++++++  Beispiel  ++++++++++
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-04-24 14:24:08 +0200
Processing by GameController#pong as HTML
  Rendered game/pong.html.erb within layouts/application (0.3ms)
Completed 200 OK in 7ms (Views: 6.7ms | ActiveRecord: 0.0ms)
Aber was ist game_pong_path? Schauen wir uns dazu die für diese Rails-Applikation generierten Routen an:
MacBook:redirect_example xyz$ rake routes
game_ping GET /game/ping(.:format) game#ping
game_pong GET /game/pong(.:format) game#pong
MacBook:redirect_example xyz$
Sie sehen, dass die Route zur Action ping des Controllers GameController den Namen game_ping bekommen hat (siehe Anfang der Zeile). Wir könnten den Redirect auch folgendermaßen schreiben:
redirect_to :action => 'pong'
Auf die Details und einzelnen Möglichkeiten des Redirects gehen wir später im jeweils konkreten Fall ein. Nur schon so viel vorweg: Man kann nicht nur auf eine andere Methode, sondern auch auf einen anderen Controller oder eine ganz andere Webseite redirecten.

Autor

Stefan Wintermeyer