5 Eine einfache Bookmarkverwaltung
Es ist so weit: Unsere erste Rails-Applikation, die wir von A bis Z erstellen, wartet auf uns!
Unsere erste Rails-Applikation wird eine Linksammlung oder Bookmarkverwaltung sein, die man zum Beispiel auf seiner Website einsetzen kann, um empfohlene Links zu veröffentlichen.
Mit Autorisierungssystem
Die Liste der angelegten Links soll öffentlich zugänglich sein, das Anlegen und Ändern der einzelnen Einträge soll aber nur durch autorisierte User möglich sein. Das heißt, unsere Applikation wird auch ein Autorisierungssystem enthalten.
Abbildung Liste der Bookmarks nicht autorisierter User
Autorisierten Usern stehen folgende Aktionen zur Verfügung:
- Neue Bookmarks erstellen
- Bookmarks anzeigen
- Bookmarks ändern
- Bookmarks löschen
Abbildung Liste der Bookmarks autorisierter User
Die Applikation soll auch sogenannte Flashmeldungen ausgeben, um das Ein- und Ausloggen oder Fehlermeldungen an der Oberfläche zu protokollieren.
5.1 Rails-Projekt erstellen 

rails
Bevor wir den ersten Controller und den ersten View für unser Beispiel erstellen können, müssen wir zuerst unsere Bookmark-Applikation anlegen:
rails bookmarkmanager
create app/controllers
create app/helpers
create app/models
...
create log/production.log
create log/development.log
create log/test.log
Rails erstellt das Verzeichnis bookmarkmanager und alle für ein Rails-Projekt erforderlichen Unterverzeichnisse und Dateien.
An dieser Struktur erkennen Sie die Umsetzung des Konzepts Konvention statt Konfiguration . Alles hat seinen vordefinierten Platz (Bilder, Javascripts usw.).
Um das Projekt im Browser zu testen, wechseln Sie in das Verzeichnis bookmarkmanager, und starten Sie über den Befehl
ruby script/server
den lokalen Rails-Server.
Lokaler Rails-Server |
Es ist durchaus praktisch, den lokalen Rails-Server in einem zweiten Konsolen-Fenster zu starten, da wir in der ersten Konsole später weitere Befehle ausführen werden. Der Rails-Server kann mit der Tastenkombination ![]() ![]() |
Lokalen Server starten
Über die Adresse http://localhost:3000 können Sie die Applikation im Browser öffnen. Es öffnet sich folgende Seite mit dem Begrüßungstext »Welcome aboard«.
Auf dieser Seite finden Sie einen Link »About your application's environment«, über den Sie zu einer Übersicht der Applikationseinstellungen gelangen. Hier finden Sie neben der Versionsnummer der zugrunde liegenden Ruby-Version auch die Versionsnummern der Subframeworks von Ruby on Rails, wie zum Beispiel ActiveRecord und des eingesetzten Datenbanksystems. Aber dazu später mehr.
Abbildung Applikationseinstellungen
Erstellung des Bookmarks-Controllers 

Steuerzentrale
Unser Ziel ist es, eine Applikation zu erstellen, die unsere Bookmarks listet. Dazu benötigen wir einen Controller. Der Controller ist nach dem Model-View-Controller-Konzept die Steuerzentrale in Rails und hat die Aufgabe, Daten aus dem Model zu lesen und sie dem View zur Verfügung zu stellen.
Abbildung Controller
Controller- Generator
Im nächsten Schritt müssen wir also einen Bookmarks-Controller erstellen. Dazu nutzen wir den controller -Generator, den uns Rails zur Verfügung stellt, um uns die Arbeit zu erleichtern. Der Generator erwartet als Pflichtparameter den Controllernamen, üblicherweise im Plural. Im Plural deshalb, weil der Controller meistens mehrere Dinge, in unserem Fall die Bookmarks, zu verwalten hat. Wechseln Sie in der Konsole in das Verzeichnis bookmarkmanager, und generieren Sie den Controller bookmarks:
ruby script/generate controller bookmarks
Man kann dem controller -Generator auch die Namen der Views, die benötigt werden, mit übergeben, aber wir wollen in diesem Beispiel zunächst darauf verzichten, weil wir aus Verständnisgründen am Anfang so wenig wie möglich automatisch generieren lassen wollen. In den nächsten Schritten zeigen wir, wie man auch die Views automatisch mitgenerieren lassen kann.
Der controller -Generator erzeugt folgende Verzeichnisse und Dateien:
exists app/controllers/ exists app/helpers/ create app/views/bookmarks exists test/functional/ create app/controllers/bookmarks_controller.rb create test/functional/bookmarks_controller_test.rb create app/helpers/bookmarks_helper.rb
Auch hier lässt sich wieder die Umsetzung des Konzepts Konvention statt Konfiguration erkennen. Das automatisch mitgenerierte View-Verzeichnis heißt wie der Controller, bookmarks, und auch die angelegten Test- und Helper-Dateien beginnen mit einem vorangestellten »bookmarks«.
Uns interessiert zunächst nur die Datei bookmarks_controller.rb im Verzeichnis app/controllers.
Projekt im Editor öffnen
Um den Controller bearbeiten zu können, öffnen Sie bitte das Projekt in einem Editor.
Unter app/controllers finden Sie die gerade eben vom Generator erzeugte Datei bookmarks_controller.rb und einen von Rails generierten Standard-Controller application.rb . Wenn Sie den Bookmarks-Controller öffnen, sehen Sie, dass er vom Application-Controller erbt:
Listing app/controllers/bookmarks_controller.rb
class BookmarksController < ApplicationController end
Das heißt, dass alles aus dem Application-Controller auch allen anderen Controllern zur Verfügung steht.
Actions
Der Bookmarks-Controller ist eine Klasse, in der Sie Methoden definieren können. Innerhalb von Controllern werden (öffentliche) Methoden Actions genannt:
class BookmarksController < ApplicationController def list render :text => "hello world" end end
Über den Ausdruck render :text => "hello world" wird der Text »hello world« ausgegeben.
Um das testen zu können, rufen Sie die Action nach folgendem Schema im Browser auf:
http://<host>:<port>/<controller>/<action>
Da die Applikation auf unserem eigenen Rechner läuft, geben wir für den Host localhost an. Der Standardport für eine Rails-Applikation ist der Port 3000. In unserem Fall lautet der Aufruf also:
http://localhost:3000/bookmarks/list
Abbildung Ausgabe »hello world«
Aufruf von index
Wenn Sie die Action list in index umbenennen, können Sie sie auch wie folgt im Browser aufrufen:
http://localhost:3000/bookmarks
Diese Konvention in Rails folgt einer ähnlichen Webserver-Konfiguration, wie Sie sie vom automatischen Aufruf der »index.html« aus Nicht-Rails-Projekten kennen.
Unsere Index-Seite soll aber die Liste aller Bookmarks anzeigen. Dazu erstellen wir im ersten Schritt ein Array mit Bookmarks, die wir ausgeben werden. Später werden die Bookmarks aus einer Datenbanktabelle gelesen:
class BookmarksController < ApplicationController def index bookmarks = ["http://www.rubyonrails.com", "http://www.ruby-lang.org"] render :text => bookmarks.join(", ") end end
Abbildung Komma-Separierte Ausgabe
Der Inhalt des Arrays wird zwar komma-separiert ausgegeben, aber alles in allem ist diese Ausgabe noch sehr trivial. Das Ergebnis sollte als HTML-formatierte Liste angezeigt werden. Diese Formatierung im Controller vorzunehmen, wäre sehr aufwendig und ist auch gar nicht die Aufgabe des Controllers. Der Controller fragt »nur« die Daten aus dem Model ab und stellt sie dem View zur Darstellung zur Verfügung. Also sollte zur Ausgabe und Formatierung der Darstellung der View verwendet werden.
View erstellen 

app/views
Ein View ist im Prinzip nichts anderes als eine Template-Datei, die in der Regel HTML-Code und Ruby-Code enthält. Die Views für den Bookmarks-Controller liegen im Ordner app/views/bookmarks, der von unserem controller -Generator miterzeugt wurde. Hätten wir dem Generator als optionale Parameter die Namen der Views übergeben, wären die entsprechenden View-Dateien miterzeugt worden. In diesem Beispiel wollen wir aber so wenig wie möglich automatisch generieren, und deshalb erstellen wir unsere Views manuell.
Abbildung View
Um einen neuen View zu erstellen, erzeugen Sie eine neue Datei im Verzeichnis app/views/bookmarks und nennen diese per Konvention genauso wie die Action im Controller, von der der View seine Daten erhält, in unserem Fall also index.html.erb . Da der View für die Darstellung im Browser verantwortlich ist, enthält diese Datei HTML-Code:
Listing app/views/bookmarks/index.html.erb
<h2>Liste der Favoriten</h2>
Um das im Browser testen zu können, müssen Sie im Controller definieren, dass der View aufgerufen wird und nicht mehr die Ausgabe der komma-separierten Liste erfolgt:
Listing app/controllers/bookmarks_controller.rb
class BookmarksController < ApplicationController
def index
bookmarks = ["http://www.rubyonrails.com",
"http://www.ruby-lang.org"]
render :template => "bookmarks/index.html.erb"
end
end
render
Über render :template => "bookmarks/index.html.erb" geben Sie an, dass das Template index.html.erb im Verzeichnis app/views/bookmarks geladen werden soll. Sie müssen allerdings nur noch den Pfad ab dem Ordner app/views angeben, da Rails davon ausgeht, dass alle Views in diesem Verzeichnis liegen. Im Browser wird jetzt der View ausgegeben:
Abbildung Ausgabe View
Die Zeile render :template => "bookmarks/index.html.erb" im Controller ist in diesem Fall nicht erforderlich, weil per Konvention definiert ist, dass sich die Views zu einem Controller in dem Ordner befinden, der so heißt wie der Controller, und dass die Views selbst so heißen wie die Action im Controller, für die sie zuständig sind. Das heißt, unser Controller enthält noch folgenden Code:
Listing app/controllers/bookmarks_controller.rb
class BookmarksController < ApplicationController def index bookmarks = ["http://www.rubyonrails.com", "http://www.ruby-lang.org"] end end
Um die Bookmarks aus dem Array im Controller im View anzeigen zu können, müssen wir den View anpassen. Zunächst wollen wir nur die komma-separierte Liste im View ausgeben:
Listing app/views/bookmarks/index.html.erb
<h2>Liste der Favoriten</h2> <%= bookmarks.join(", ")%>
Hierbei ist folgende Syntax zu beachten:
Syntax für Ruby-Code
Ruby-Code wird im View zwischen folgende Zeichen gesetzt: <% und %> . Soll etwas aus Ruby heraus ausgegeben werden, wird noch ein Gleichheitszeichen gesetzt: <%= Ruby-Ausgabe %>.
Wann immer etwas aus der Datenbank ausgelesen und an der Oberfläche ausgegeben wird, sollte die Ausgabe mit Hilfe der Methode html_escape oder kurz h erfolgen, damit Tag-spezifische Zeichen wie <, > und & maskiert werden und dadurch verhindert wird, dass eventuell bösartig eingegebene Befehle ausgeführt werden.
Zum Beispiel wird beim Aufruf von
<%= h '<script>alert("!!!")</script>' %>
folgender HTML-Code generiert:
\<script\>alert("!!!")\</script\>
Wenn Sie die Bookmarkliste im Browser aufrufen, erhalten Sie die Fehlermeldung »undefined local variable or method 'bookmarks'«:
Abbildung Fehlermeldung
Instanzvariablen
Das liegt daran, dass im Controller das Array bookmarks nicht als Instanzvariable (Variablen mit führendem @ -Zeichen) definiert wurde. Instanzvariablen stehen allen Methoden innerhalb des Controllers, in dem sie definiert wurden, und den zugehörigen Views zur Verfügung.
Änderung im Controller:
Listing app/controllers/bookmarks_controller.rb
class BookmarksController < ApplicationController def index @bookmarks = ["http://www.rubyonrails.com", "http://www.ruby-lang.org"] end end
Änderung im View:
Listing app/views/bookmarks/index.html.erb
<h2>Liste der Favoriten</h2> <%= @bookmarks.join(", ") %>
Abbildung Komma-separierte Liste im View
HTML-formatierte Liste
Eigentlich wollten wir aber eine HTML-formatierte Liste ausgeben. Dazu können wir eine HTML-Liste benutzen, deren Werte wir über eine Schleife setzen:
Listing app/views/bookmarks/index.html.erb
<h2>Liste der Favoriten</h2> <ul> <% @bookmarks.each do |bookmark|%> <li><%= bookmark %></li> <% end %> </ul>
Abbildung HTML-formatierte Liste im View
Später werden die einzelnen Bookmarks aus einer Datenbank gelesen. An dem View muss sich dann nichts mehr ändern, da der View nicht weiß und auch nicht wissen muss, woher die Daten kommen.
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.