Nachdem man Ruby on Rails 3 auf seinem Entwicklungsserver eingerichtet hat, kann man sich sofort hinter die Entwicklung einer ersten Testapplikation machen.
Meine Anleitung richtet sich an Web-Entwickler, die mit einem PHP-Hintergrund Ruby on Rails ausprobieren möchten und mit dem MVC-Paradigma vertraut sind (sprich schon mit dem Zend Framework, Symfony, CakePHP etc. produktiv gearbetiet haben).
Vorbemerkung: Versionschaos
Im Netz gibt es unzählige How-Tos und Tutorials um eine erste Rails-Applikation hinzubiegen — sehr hilfreich war für mich Enabling Rails 3 for your application. Leider beziehen sich die wenigsten Anleitungen auf Ruby on Rails 3. Leider vernachlässigen es die Autoren solcher Werke oftmals zudem, darauf hinzuweisen, auf welche Rails-Version sich die Anleitung denn eigentlich bezieht. Dies hole ich hier explizit vor — meine Version lautet:
$ rails -v Rails 3.0.4
Notabene: Es gibt anscheinend die Möglichkeit, mit der neuesten Rails-Version auch Projekte anzulegen, welche nach einer der älteren Versionen aufgebaut sind (rails _2.3.5_ APP_NAME via How can I create previous version rails in rails 3?). Wenn aber jemand Rails lernen möchte, sollte er dies mit der aktuellsten Version tun — so meine Überzeugung.
Beispielapplikation: Arbeitsjournal
Um rasch Gemeinsamkeiten und Unterschiede zu PHP aufzuzeigen, habe ich mich hierbei entschlossen, eine bestehende PHP-Webapplikation mit Ruby on Rails nachzubauen: Das Arbeitsjournal. Mit diesem führe ich für einen meiner derzeitigen Jobs Buch, wie lange ich arbeite und welche Aufgaben ich wann erledigt habe. Das Tool zeigt mir die Gesamtarbeitszeit für einen Monat und berechnet auch gleich, ob ich die gemäss Arbeitsvertrag erforderlichen Stunden abgearbeitet habe oder nicht.
Der Projekttitel liegt auf der Hand: arbeitsjournal.
Applikations-Skelett erstellen
Ich habe mich entschieden, meine Projekte unter /var/rails abzulegen. Nachdem ich dieses Verzeichnis erstellt habe, welches alle zukünftigen Ruby-Projekte enthält, wechsle ich da hinein und erstelle mir die Projektstruktur. Dank Rails ist dies Sache eines einzigen Befehls:
# mkdir /var/rails $ cd /var/rails $ rails new arbeitsjournal -d mysql
Die Option -d gibt an, dass man die Modelle und Daten in einer MySQL-Datenbank abgelegt haben möchte (Standard ist sqlite3)
Datenbankverbindung herstellen
Als Datenbank habe ich MySQL gewählt. Das Vorgehen ist identisch wie bei PHP-Web-Projekten: Zuerst erstellt man sich eine Datenbank (bei mir ruby_arbeitsjournal), einen MySQL-Benutzer (ruby) mitsamt Passwort und weist ihm Schreibrechte auf die neu erstellte Datenbank zu. Nach einem FLUSH PRIVILEGES; liest die MySQL-Datenbank den neuen Benutzer ein. Ich verwende dazu als Relikt vergangener Tage das GUI phpMyAdmin, obwohl ich auf der MySQL-Kommandozeile mittlerweile viel rascher ans Ziel kommen würde.
Unter Rails gibt man die Datenbankoptionen in der Datei ~/config/database.yml an:
... development: adapter: mysql database: ruby_arbeitsjournal host: localhost username: ruby password: ******** ...
Modell erstellen
Nun ist es an der Zeit, das Modell zu erstellen. Da es sich um eine Applikation mit ein, zwei Datenbanktabellen handelt, welche wiederum kaum Felder beinhalten, kann man dies bequem auf der Kommandozeile machen. Als Objektbezeichnung für einen Arbeitszeiteintrag habe ich mich an die gute, alte Stempeluhr erinnert und das Objekt deshalb Stamp genannt:
$ rails generate scaffold Stamp date_start:datetime date_end:datetime description:text
Das Objekt heisst Stamp und es weist drei Felder auf: date_start, date_end und description, denen die jeweiligen Titel zugewiesen werden. Nützlich war mir hier eine Liste der für’s Scaffolding verfügbaren Feldtypen.
Dies erstellt den Controller, welcher für das Auflisten (index), Anzeigen (show), Erstellen (new), Speichern (create) Editieren (edit), Aktualisieren (update) und Löschen (destroy) zuständig ist. Natürlich ohne, dass ich als Entwickler eine einzige Zeile Code schreiben muss. Genial!
Datenbanktabelle erstellen
Zuletzt erstellen wir nun die physische Tabelle in MySQL:
$ rake db:migrate --trace
Webserver starten
Ich habe einige Zeit damit verbraten, die Applikation über Apache 2 bereitzustellen. Leider momentan noch fruchtlos, u.a. weil sich die Anleitungen auf Rails 2 beziehen, welches offenbar noch ein dispatch.fcgi mit sich brachte. Dies fehlt im DocumentRoot ~/public einer 3er-Applikation.
Die Verwendung von Apache ist dabei gar nicht zwingend nötig — für Web-Entwickler stellt Rails (natürlich!) einen eigenen rudimentären Web-Server zur Verfügung. Man startet diesen über
$ cd /var/rails/arbeitsjournal # rails server
Aus dem Intranet kann man nun auf den Testserver zugreifen, indem man Port 3000 anspricht. In meinem Falle war dies mad4you.homeip.net:3000.
Routing einrichten
Wer obigen Link aufruft, erhält die Standard-Willkommensseite für Rails-Projekte zu gesicht, die unter ~/public/index.html abgelegt ist.
Benennt man diese Datei kurzerhand um, kriegt man eine Fehlermeldung zu Gesicht. Rails kann nämlich nicht hellsehen und weiss nicht, was der Benutzer eigentlich für eine Seite angezeigt erhalten möchte. Ein Abstecher in die Routing-Datei ~/config/routes.rb und eine klitzekleine projektbezogene Anpassung hilft weiter:
... root :to => "stamps#index" ...
Auf Deutsch: Diese Anweisung sagt Rails, dass falls ein Request namens GET / reinkommt, dieser auf die Stamps-Objekte weitergeleitet werden soll und dort die Auflistung aller Datenbankwerte
Views und Helper anpassen
Jetzt folgt die Knochenarbeit — zum ersten Mal muss Ruby programmiert werden. Hier sollte sich jeder Web-Entwickler rasch heimisch fühlen, denn abgesehen von einer anderen Programmiersprache ist das Vorgehen nun jedem mit dem MVC-Paradigma vertrauten Entwickler bekannt: Views anpassen, Helper-Funktionen entwickeln und im Controller Kollisionsabfragen etc. implementieren.
Die Pfade zu den entsprechenden MVC-Elementen lauten in meinem Fall:
- ~/app/models/stamb.rb
- ~/app/views/stamps/*.html.erb
- ~/app/controllers/stamps_controller.rb
Insbesondere in ~/app/views/stamps/index.html.erb kann man genügend rumfuhrwerken. Hier vermischen sich HTML-Code und Ruby-Code, und hier kann der Entwickler genauestens steuern, wie die erfassten Daten ausgegeben respektive ausgewertet werden sollen.
Sehr wichtig ist ~/app/helpers/stamps_helper.rb, um die View nicht mit Ruby-Code zu überladen. Dorthin lagert man sich alle nützlichen kleinen Methoden aus, die mehrmals im Code benutzt werden und es deshalb Sinn macht, Redundanzen zu vermeiden.
Fertig? Fertig!
Ab jetzt verfügt man über eine funktionierende Web-Applikation, um Arbeitsstunden zu erfassen. Rails hat die entsprechenden Controller-Aktionen automatisch bereitgestellt und ich kann sofort mit dem Einfüllen von Daten beginnen.
In einem weiteren Artikel werde ich mich um einige Finessen kümmern, die für PHP-Entwickler anders, ungewohnt, oftmals aber äusserst erleichternd sind.