Routing 

Unsere Bookmarkverwaltung ist zwar prinzipiell fertig, aber sie zeigt noch ein Verhalten, das uns nicht ganz gefällt.
Zu der Startseite unserer Applikation gelangen wir nur über den Aufruf:
http://localhost:3000/bookmarks
Wenn wir das »/bookmarks« weglassen, also nur »http://localhost:3000« aufrufen, öffnet sich die Willkommen-Seite von Rails.
Bis jetzt haben wir gesagt, dass die URL folgendem Aufbau folgt:
Host/controller/action/id
Alle Links innerhalb unserer Bookmarkverwaltung sind entsprechend aufgebaut. Das heißt, wir geben immer den Controller und die Action an, die wir aufrufen möchten.
routes.rb
Aber warum das so ist, sind wir bis jetzt schuldig geblieben. Das sogenannte 5.10 Routing legt fest, welcher interne Aufruf aus der URL erfolgt. Die Datei, in der das Routing definiert wird, heißt routes.rb und befindet sich im Verzeichnis config:
Listing config/routes.rb
ActionController::Routing::Routes.draw do |map| # ... # See how all your routes lay out with "rake routes" # Install the default routes as the lowest priority. map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format' end
Für uns ist zunächst nur folgender Eintrag relevant:
map.connect ':controller/:action/:id'
Dieser Eintrag legt fest, dass, wenn zum Beispiel folgende URL aufgerufen wird:
http://localhost:3000/bookmarks/show/1
Abbildung Diagramm Routing
Der erste Teil des Aufrufs entspricht dem Hostanteil, in unserem Fall localhost:3000, normalerweise eine Domain. Der zweite Teil wird dem Controller zugeordnet, der dritte der Action und der vierte der ID. Konkret passiert intern folgende Zuordnung:
- params[:controller] = "bookmarks"
- params[:action] = "show"
- params[:id] = 1
Die Controller-Klasse heißt Bookmarks-Controller, wird also über den Namen gefunden. Auch die Action innerhalb des Controllers wird über den Namen gefunden. Innerhalb der Action kann der Zugriff auf die ID über params[:id] erfolgen.
Eigene Routingeinträge
Wenn wir eine von dieser Logik abweichende URL aufrufen möchten, müssen wir einen eigenen Routing-Eintrag vornehmen. Eine andere URL nutzen zu wollen, ist vor allem sinnvoll, weil wir uns zum Setzen der einzelnen Links unserer Bookmarkverwaltung nicht mehr merken wollen, welche Action zu welchem Controller gehört. Das heißt, das Setzen von :controller und :action soll durch den Aufruf einer URL, zum Beispiel /login, ersetzt werden.
Wenn in der URL /login aufgerufen wird, soll sich die Log-in-Seite öffnen, es sollen also der Controller authentication und die Action login aufgerufen werden. Gleiches soll auch für das Abmelden, also den Aufruf /logout, möglich sein.
Solche eigenen Einträge in der routes.rb sollen immer oberhalb des Standardeintrags von Rails erfolgen:
Listing config/routes.rb
ActionController::Routing::Routes.draw do |map| # The priority is based upon order of creation: # first created -> highest priority. # Sample of regular route: # map.connect 'products/:id', :controller => 'catalog', # :action => 'view' # Keep in mind you can assign values other than # :controller and :action ... map.connect 'login', :controller => "authentication", :action => "login" map.connect 'logout', :controller => "authentication", :action => "logout" # Install the default route as the lowest priority. map.connect ':controller/:action/:id.:format' map.connect ':controller/:action/:id' end
Bevor wir das im Browser testen, müssen wir den lokalen Rails-Server neu starten.
Immer Server nach Änderung am Routing neu starten |
Immer wenn wir Änderungen am Routing vornehmen, müssen wir den lokalen Server neu starten. Der lokale Server kann mit
![]() ![]() |
Abbildung http://localhost:3000/login
Links anpassen
Wir haben jetzt für das An- und Abmelden vereinfachte Pfade und können die Links zum Log-in bzw. Log-out in der application.html.erb entsprechend anpassen:
Listing app/views/layouts/application.html.erb
... <div id="footer" > © 2007 | <% if admin? %> <%= link_to "logout", "/logout" %> <% else%> <%= link_to "login", "/login" %> <% end %> </div>
Auch die Angabe des Controllers und der Action, an die das Log-in-Formular gesendet werden soll, kann mit Hilfe eines eigenen Routing-Eintrages vereinfacht werden:
Listing config/routes.rb
ActionController::Routing::Routes.draw do |map|
# ...
map.connect 'login', :controller => "authentication",
:action => "login"
map.connect 'logout', :controller => "authentication",
:action => "logout"
map.connect 'check', :controller => "authentication",
:action => "check"
# Install the default route as the lowest priority.
map.connect ':controller/:action/:id.:format'
map.connect ':controller/:action/:id'
end
In dem Template login.html.erb können Sie den Aufruf der Methode form_tag entsprechend anpassen:
Listing app/views/authentication/login.html.erb
<h2>Login</h2> <% form_tag "/check" do %> ...
Benannte Routen 

map.name
Eine bessere Alternative ist jedoch, die Routing-Einträge in routes.rb zu benennen, also sogenannte benannte Routen anzugeben. Statt mit map.connect werden benannte Routen mit map.name angelegt. Als Namen kann man frei gewählte Begriffe nehmen, in unserem Fall bieten sich »login« und »logout« für das An- und Abmelden und »check« für die URL, an die das Log-in-Formular gesendet werden soll, an:
map.login 'login', :controller => "authentication", :action => "login" map.logout 'logout', :controller => "authentication", :action => "logout" map.check 'check', :controller => "authentication", :action => "check"
Das Benennen der Einträge bewirkt, dass automatisch zwei Methoden pro Eintrag definiert werden:
»name«_url, »name«_path
login_url, login_path, logout_url, logout_path, check_url und die Methode check_path . »name«_url liefert die absolute URL inklusive des Hosts. »name«_path liefert den relativen Pfad ohne den Host, also das, was dem Methodenaufruf map.name als erster Parameter übergeben wurde, mit führendem Slash. Um die Links in der application.html.erb anzupassen, reichen uns die Methoden login_path und logout_path:
<div id="footer" > © 2007 | <% if admin? %> <%= link_to "logout", logout_path %> <% else%> <%= link_to "login", login_path %> <% end %> </div>
Im Log-in-Formular setzen wir die Methode check_path ein:
Listing app/views/authentication/login.html.erb
<h2>Login</h2> <% form_tag check_path do %> ...
Die root-Route 

map.root
Wenn wir in der URL keinen Controller angeben, also nur den Host aufrufen, wird die Willkommen-Seite von Rails angezeigt. Das liegt u. a. daran, dass Rails nicht weiß, welcher Controller in diesem Fall angezeigt werden soll. Noch nicht. In routes.rb existiert ein Beispieleintrag, wie man eine Route für den Root-Pfad der Applikation anlegt:
Listing config/routes.rb
# You can have the root of your site routed with map.root -- # just remember to delete public/index.html. # map.root :controller => "welcome"
Wenn unsere Bookmarkverwaltung ohne Pfadangabe aufgerufen wird, soll die Index-Seite des Controllers bookmarks angezeigt werden:
map.root :controller => "bookmarks"
Wir haben keine Action angegeben, die aufgerufen werden soll, da per Konvention die Action index aufgerufen wird, wenn keine Action angegeben wird.
public/index.html
Wenn Sie den Rails-Server neu starten und dann http://localhost:3000 aufrufen, wird immer noch die Willkommen-Seite von Rails angezeigt. Das liegt nicht daran, dass unser Routing-Eintrag fehlerhaft ist, sondern daran, dass sich diese Willkommen-Seite im Verzeichnis public befindet und index.html heißt. Alles, was im Verzeichnis public liegt, wird bevorzugt verwendet. Wenn sich dort eine index.html befindet, wird der Routing-Eintrag für den Aufruf ohne Pfadangabe ignoriert. Das heißt, wir müssen die Datei umbenennen oder löschen. Wenn Sie das tun und anschließend noch einmal http://localhost:3000 aufrufen, wird die von uns eingetragene Index-Seite unserer Bookmarkverwaltung angezeigt.
Abbildung Startseite
root_path
Da wir eine Route für den Root-Pfad unserer Applikation angelegt haben, steht uns jetzt die Methode root_path zur Verfügung, um unsere Links »Zurück zur Liste« in den einzelnen Views zu setzen. Im Abschnitt 5.8 haben wir eine Helper-Methode zur Generierung dieses Links angelegt. Das heißt, wir müssen die Änderung der Pfadangabe nur an einer Stelle in der bookmarks_helper.rb ändern:
Listing app/helpers/bookmarks_helper.rb
module BookmarksHelper
def back_to_list
content_tag(:div,
link_to ("Zurück zur Liste", root_path),
:class => "subNavigation")
end
end
Über das Routing haben wir jetzt zwei Dinge gelernt:
- Wenn wir benannte Routing-Einträge vornehmen, stehen uns die Methoden »name«_url und »name«_path zur Verfügung.
- Beim Anlegen eines Routing-Eintrags für den Root-Pfad der Applikation müssen wir daran denken, im Verzeichnis public die Datei index.html umzubenennen oder zu löschen.
Ihre Meinung
Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.