Die Analyse des Web-Frameworks Ruby on Rails (Rails), ist eines von fünf Arbeitsthemen des Spezialisierungsthemengebietes „Web-Engineering“ der Fachhochschule Technikum Wien.
Die Ausarbeitung basiert auf der Beispielanwendung Yet Annother Community (YAC). Diese Applikation wurde von den fünf Studenten des Spezialisierungsthemengebietes „Web-Engineering“ ausgewählt und zwei exemplarische Use Cases wurden implementiert. Beide Use Cases wurden vollständig vertikal implementiert, um herauszufinden wie Rails den agilen Entwicklungsprozess und das Rapid Application Development unterstützt.
Die Vorbereitungsarbeiten (Aufbau der Datenbank, generieren des Rails-Projektes, Scaffolding, Objektrelationales Mapping) für die Implementierung der beiden Use Cases hat gezeigt, dass Rails ein sehr stabiles und zuverlässiges Web-Framework ist und den Programmierer effizient bei der Entwicklung von Webapplikationen mit agilen Prozessen unterstützt.
Alle Hauptanforderungen und die beiden Use Cases „Registrieren eines Users“ und „Login eines Members“ wurden mit den Rails Generatoren „Action Mailer“, „Login_generator“, „Scaffold Generator“ und Modifikationen in den Controllern und Views implementiert. Diese Generatoren bauen eine sehr klare MVC-Struktur auf und erleichtern dadurch die Anpassung der Web-Applikation.
Das konsequente Verfolgen und Umsetzen der MVC Architektur in Verbindung mit den Active Records und den Prinzipien DRY und „Konventionenen statt Konfigurationen“ machen Rails zu einem sehr agilen Web-Framework und daher auch zu einem perfekten Tool für Rapid Application Development.
Inhaltsverzeichnis
1. Problem- und Aufgabenstellung
2. Einleitung
2.1. Motivation
2.2. Einschränkungen
3. Grundlagen
3.1. Ruby
3.1.1. Geschichtliche Entwicklung
3.1.2. Programmierparadigmen
3.1.3. Programmaufbau
3.1.4. Basistypen
3.1.5. Flusskontrolle
3.1.6. Klassen und Objekte
3.1.7. Module und Mixins
3.2. Rails
3.2.1. Model-View-Controller Konzept (MVC)
3.2.2. MVC Umsetzung in Rails
3.2.3. Konfiguration von Rails
3.2.4. Namenskonventionen
3.2.5. Active Records
3.2.6. Layout Templates und Partials
3.2.7. Generatoren
4. Praktischer Teil
4.1. Use Cases
4.1.1. Actoren
4.2. Entity-Relationship-Modell
4.3. Testumgebung
4.4. Umsetzung der zwei exemplarischen Use Cases
4.4.1. Vorgehensweise
4.4.2. Einrichten der Datenbank
4.4.3. Erstellen des Rails-Projektes und Konfiguration
4.4.4. Konfiguration der Startpage
4.4.5. Vertikale Implementierung des Use-Cases „Einloggen eines Members“
4.4.6. Vertikale Implementierung des Use-Cases „Registrieren eines Users“
5. Diskussion
5.1. Das MVC-Konzept
5.2. Active Records
5.3. DRY und Konventionen-statt-Konfigurationen
5.4. Conclusio
6. Abbildungsverzeichnis
7. Abkürzungsverzeichnis
8. Literaturverzeichnis
9. Anhang
1. Problem- und Aufgabenstellung
Die Analyse des Web-Frameworks Ruby on Rails (Rails), ist eines von fünf Arbeitsthemen des Spezialisierungsthemengebietes „Web-Engineering“ der Fachhochschule Technikum Wien.
Das Themengebiet „Web-Engineering“ umfasst zusätzlich noch die Themen „Analyse und Vergleich bestehender Web-Frameworks“, „Analyse und Design einer Beispielanwendung zur Analyse von Web-Framworks“,“ Analyse des Web-Framework Java Server Faces anhand einer Beispielanwendung“ und “Vergleich von Ruby on Rails mit dem PHP-Webframework WebLIOS“.
Da es auf dem Gebiet des Web-Engineerings zahlreiche unterschiedliche Web-Frameworks gibt, soll mit diesen Arbeiten ein Überblick über aktuelle Web-Technologien und Web-Frameworks geschaffen werden.
Alle Arbeitsthemen und die behandelnden Web-Frameworks basieren auf der selben Beispielanwendung. Anhand dieser Anwendung, die von allen fünf Studenten ausgewählt und designed wurde, werden zwei exemplarische Use Cases vertikal implementiert, um damit die Funktionsweise und Aspekte von Ruby on Rails analysieren und beschreiben zu können. Die Implementierung umfasst die Erstellung des Graphical User Interfaces sowie der Geschäftslogik und der Datenzugriffsschicht. Durch die vollständige Entwicklung dieser Schichten mit Ruby on Rails soll herausgefunden werden, wie dieses Web-Framework den Entwickler bei der Implementierung und Programmierung unterstützt. Besonderes Augenmerk liegt auf dem agilen Softwareentwicklungsprozess.
2. Einleitung
2.1. Motivation
Die Gegenbewegung zu den formalen Softwareentwicklungsprozessen ist die sogenannte Agile Softwareentwicklung, die seit den ersten Ansätzen von vielen Firmen in der Entwicklung ihrer Software immer häufiger eingesetzt wird [AGILE01].
Diese steigende Tendenz ist verständlich, denn die Vergangenheit hat gezeigt, dass oftmals der Kundenwunsch und das Verständnis der Entwickler bezüglich der Anforderungen nicht übereinstimmen.
Dies führte dazu, dass Teile der Applikationen nochmal analysiert, redesigned und neu implementiert werden mussten.
Wurde jedoch zuerst ein sehr aufwendiger und zeitintensiver Analyse- und Designprozess durchlaufen, um solche Fehler zu vermeiden, explodierten die Kosten schon zu Beginn eines Projektes, ohne das noch eine Zeile Code geschrieben wurde. Für nicht so umfangreiche Softwareprodukte war so ein Vorgehensmodell ineffizient. Mit den ersten Ansätze der agilen Softwareentwicklung wurde versucht, den Softwareentwicklungsprozess zu verbessern und vorzeigbare Teile der Software schneller zu erhalten. Mit dem Buch Extreme Programming von Kent Beck erlangte das agile Vorghensmodell große Popularität [AGILE02]. Primär befasst sich diese Arbeit mit den Grundprinzipien der Agilen Softwareentwicklung und der Integration in Ruby on Rails.
Die Motivation für diese Arbeit liegt im grundsätzlichen Interesse an der Web-Entwicklung und im speziellen am Interesse an Web-Frameworks, womit der agile Entwicklungsprozess und das Rapid Application Development (RAD) vielschichtig umsetzbar ist.
Ziel
Mit dieser Arbeit sollen die Prinzipien, Konzepte und die Möglichkeiten der agilen Softwareentwicklung des Web-Framework Rails untersucht und analysiert werden. Die Basis für diese Untersuchung ist die Beispielanwendung „Yet Another Community“ (YAC), die von fünf Studenten des Spezialisierungsthemengebietes „Web-Engineering“ entworfen wurde. Auf Basis dieser Applikation werden zwei exemplarische Use Cases vertikal implementiert und der Implementierungsprozess beschrieben.
Inwieweit Rails den agilen Softwareentwicklungsprozess unterstützt, welche Stärken dieses Web-Framework bietet und welche Schwächen aufgezeigt werden können, wird in der Diskussion erarbeitet.
Mittels der vollständig vertikalen Implementierung der Use Cases werden die vier Grundkonzepte von Rails im speziellen diskutiert:
1. DRY-Prinzip:
Dieses Prinzip ist auch unter den Namen „Once and only Once“ oder „Single Point of Truth (SPOT)“ bekannt. Ziel und Philosophie dieses Prozesses ist es, Duplikate und Wiederholungen zu verringen. „In Rails muss ein Sachverhalt genau einmal programmiert bzw. beschrieben werden [ROR01, S. 2].
2. Konventionen statt Konfigurationen-Prinzip:
Statt Konfigurationsdateien werden in Rails Zusammenhänge über Namenskonventionen behandelt.
3. Model-View-Controller Konzept:
Ein flexibles Programmdesign gewährleistet die Wiedeverwendbarkeit von einzelnen Komponenten und ermöglicht eine einfache Erweiterung der Web-Applikation.
Das Model-View-Controller(MVC) Prinzip ist ein Design-Pattern, welches Applikationen in drei voneinander getrennte Bereiche aufteilt: dem Datenmodell (Model), der Programmsteuerung (Controller) und der Präsentation (View)
Objektrelationales Mapping:
Da Datenbestände in relationalen Datenbanksystemen gehalten werden, die Programmierung jedoch objektorientiert ist, müssen Objekte und relationale Daten zusammengeführt bzw. gemappt werden. Dies bedeutet das eine Tabelle in ein Objekt und vice versa abgebildet wird.
2.2. Einschränkungen
Diese Arbeit wird ausschließlich die Aspekte von Rails betrachten und keinen Vergleich mit anderen Web-Frameworks erstellen. Aus diesem Grund werden die Beispielimplementierungen auch nicht hinsichtlich ihrer Performance untersucht, sondern lediglich der Prozess der Entwicklung und die Umsetzung der in Punkt 2.2 beschrieben Kernkonzepte.
Wirtschaftliche Aspekte werden in dieser Arbeit nicht betrachtet, sondern der Fokus auf die technischen Implementierungsabläufe und die daraus resultierenden Ergebnisse gerichtet.
3. Grundlagen
3.1. Ruby
Die Programmiersprache Ruby ist die Basis von Rails. Die zentralen Elemente dieser Sprachen werden in den folgenden Abschnitten beschrieben.
3.1.1. Geschichtliche Entwicklung
Ruby wird seit 1993 von dem Japaner Yukihiro „Matz“ Matsumoto entwickelt. 1995 wurde sie im Internet zum erstenmal veröffentlicht und ab dem Jahr 2000 wurde Ruby durch erste nicht-japanische Literatur auch in Europa und Amerika bekannt.
Ruby ist derzeit mit der aktuellen Version 1.8.5 veröffentlicht und grundsätzlich ist der Interpreter und die Standardbibliothek unter den Bedingungen der General Public License (GPL) nutzbar. Der Interpreter kann Plattformunabhängig eingesetzt werden und läuft auf allen POSIX(Portable Operating System Interface for Unix)-kompatiblen Systemen sowie auf Microsoft Windows.
Desweiteren gibt es eine inoffizielle Implementierung namens JRuby. Der JRuby-Interpreter wurde vollständig in Java entwickelt, um Ruby problemlos in Java-Environments integrieren zu können [RUB01].
3.1.2. Programmierparadigmen
Das einer Programmiersprache oder Programmiertechnik zugrundeliegende Prinzip wird als Programmierparadigma bezeichnet [PAR01].
Ruby ist eine objektorientierte, interpretierte Programmiersprache und wird auch als „Multiparadigmen-Sprache“ bezeichnet, da es nicht nur ein Programmierparadigma unterstützt und somit der Softwarentwickler die Wahl hat, bei der Erstellung seiner Programme, ein oder mehreren Paradigmen zu folgen [RUB01].
3.1.2.1. Objektorientiertes Programmierparadigma
Ruby ist vollständig objektorientiert. Alles was in Ruby manipuliert werden kann und das Resultat einer solchen Manipulation ist bzw. ergibt ein Objekt [ROR02].
Dies bedeutet, dass selbst primitive Datentypen und Konstanten Objekte sind.
Imperatives Programmierparadigma
Jedes Ruby Programm wird in einem globalen main-Objekt erstellt. Daher ist es im Gegensatz zu Sprachen wie Java oder C# nicht notwendig die Programme explizit in einer Klasse zu definieren, diese wiederholende Deklaration kann somit weggelassen werden [RUB01].
3.1.2.2. Funktionales Programmierparadigma
Funktionale Programme sind eine Menge von (Funktions)-Definitionen, die man mathematisch als partielle Abbildungen von Eingabedaten auf Ausgabedaten auffassen kann [PAR01].
In Ruby können Probleme auch funktional behandelt werden, da alles einen Wert hat [ROR01].
3.1.3. Programmaufbau
Ruby-Programme können in 7-bit ASCII, Kanji oder UTF-8 Zeichencodierung geschrieben werden.
Ruby ist eine zeilenorientierte Sprache, bei der eine Anweisung oder ein Statement mit einem Zeilenumbruch abgeschlossen wird, außer das letzte Zeichen ist ein Operator, Komma oder ein Backslash. Ein Semikolon trennt mehrere Anweisungen in einer Zeile [ROR02].
3.1.4. Basistypen
3.1.4.1. Zahlen
Alle Klassen für Zahlen werden von der abstrakten Klasse Numeric abgeleitet. Alle Zahlen sind Objekte der der Klassen Fixnum oder Bignum [ROR02].
Fixnum: systemabhängig entweder -230 bis 230 oder von -262 bis 262 -1
Bignum: Alle Zahlen die größer oder kleiner als Fixnum sind
Numerische Zeichen mit einem Dezimalpunkt oder einem Exponenten werden in einem Floatobjekt gespeichert. Wichtig dabei ist das vor oder nach dem Dezimalpunkt eine Zahl folgen muss.
Abbildung in dieser Leseprobe nicht enthalten
3.1.4.2. Zeichenketten
Jede Zeichenkette ist in Ruby ein Objekt vom Typ String. Eine Zeichenkette kann mit einem einfachen Hochkomma oder einem doppelten Anführungszeichen generiert werden. Der Unterschied zwischen diesen Methoden liegt in der Ersetzung von Zeichen.
Beide Mechanismen konvertieren einen doppelten Backslash \\ in einen Backslash \. Die geringste Ersetzung erreicht man durch das Generieren eines Strings mit einfachem Hochkomma.
Abbildung in dieser Leseprobe nicht enthalten
Beim Generieren eines Strings mit doppelten Anführungszeichen wird eine zusätzliche Ersetzung durchgeführt.
Abbildung in dieser Leseprobe nicht enthalten
Abbildung 1: Ersetzungen bei Stringzuweisung durch doppeltes
Anführungszeichen [ROR02, S. 306]
Die Klasse String implementiert die Module Comparable und Enumerable. Jedes Stringobjekt verfügt somit über die in Abbildung 2 aufgelisteten Methoden.
Abbildung in dieser Leseprobe nicht enthalten
Abbildung 2: Methoden der Module Comparable und Enumerable [ROR02, S. 585]
3.1.4.3. Symbole
Symbole repräsentieren Zeichenketten und Namen und sie sind Objekte. Symbole mit dem selben Namen werden nur einmal initialisiert und existieren im Speicher ebenfalls nur einmal [GLU01].
Abbildung in dieser Leseprobe nicht enthalten
Abbildung 3: Speicheradresse von Ruby Symbol [GLU01]
3.1.5. Flusskontrolle
nil-Objekt
Bei Variablen ohne Wert und Methoden, die keinen Wert zurückliefern, wird das nil-Objekt von Ruby verwendet. Mit diesem ist es möglich zu unterscheiden ob eine Variable oder der Rückgabewert dem dezimalen Wert 0 oder gar keinem Wert entspricht [ROR01, S.230].
True und False – Boolesche Ausdrücke
In Ruby wird alles was nicht die Konstante false oder das nil-Objekt ist, als wahr angesehen. Im Unterschied zu anderen Programmiersprachen wird somit die Zahl 0 und ein leerer String als wahr angesehen [ROR01, S. 249].
Konditionale (if und unless)
Die verzweigte Auswertung von booleschen Werten kann in Ruby mit if- bzw. unless-Anweisungen realisiert werden. Im Gegensatz zu anderen Sprachen werden keine Klammern verwendet. Die ausführenden Blöcke werden entweder durch das Schlüsselwort „end“ oder durch eine gültige Verzweigung (else oder elsif) abgeschlossen.
Das If-Statement kann auch am Ende eines einzelnen Blockes gestellt werden.
Case-Anweisung
Bei der Auswertung von mehreren Optionen, kann in Ruby die Case-Anweisung verwendet werden. Diese wird mit dem Schlüsselwort „case“ eingeleitet. Die anschließenden Vergleichsausdrücke werden mit dem Schlüsselwort „when“ begonnen. Trifft keine der angeführten Vergleichsausdrücke zu, wird die Anweisung im else-Block ausgeführt [ROR01, S. 251].
Schleifen und Iteratoren
Neben den Zählschleifen (for-Schleife) und den Kopf- bzw. Fussgesteuerten Schleifen (until und while) bieten die Klassen selbst Methoden, um Schleifen zu erstellen. Die Klasse Integer besitzt die Methoden downto, upto und times. Mit diesen Methoden können Zählschleifen realisiert werden.
Abbildung in dieser Leseprobe nicht enthalten
Abbildung 4: times-Methode der Klasse Integer [ROR02, S. 481]
Methoden
Methodendefinition:
Abbildung in dieser Leseprobe nicht enthalten
Abbildung 5: Methodendefintionssyntax [ROR02, S. 330]
3.1.6. Klassen und Objekte
In Ruby werden alle Klassen von der Basisklasse Object abgeleitet. Eine Klassendefinition wird mit dem Schlüsselwort class eingeleitet und endet mit dem Schlüsselwort end. Klassennamen beginnen mit einem Großbuchstaben. Methodennamen beginnen mit eimen Kleinbuchstaben oder Underscore und die Attribute der Klasse werden am Beginn mit einem Klammeraffen definiert [ROR01, S. 261].
Abbildung in dieser Leseprobe nicht enthalten
Abbildung 6: Klassendefinitionssyntax [ROR02, S. 337]
Eine Klasse kann die Methode initialize besitzen. Diese Methode ist der „Konstruktor“ der Klasse. Eine Klasse darf nur eine initialize-Methode besitzen. Beim Erstellen eines Objektes mit der .new Methode wird die initialize-Methode ausgeführt.
Abbildung in dieser Leseprobe nicht enthalten
3.1.7. Module und Mixins
Module fassen Methoden, Klassen und Konstanten zusammen. Module besitzen einen eigenen Namespace und können dadurch von anderen Modulen unterschieden werden. Ein Modul wird in Ruby mit dem Schlüsselwort module zu Beginn definiert und mit dem Schlüsselwort end abgeschlossen.
Abbildung in dieser Leseprobe nicht enthalten
Abbildung 7: Moduldefinitionssyntax [ROR02, S. 339]
3.2. Rails
David Heinemeier Hansson stellte 2004 die erste Beta-Version des Web-Frameworks Rails, welches vollständig in Ruby programmiert wurde, zur Verfügung. Im Dezember 2005 wurde die erste Produktionsversion freigegeben [ROR01]. Die folgenden Abschnitte beschreiben und erklären die Konzepte und Funktionsweise von Rails.
3.2.1. Model-View-Controller Konzept (MVC)
In der Softwareentwicklung gibt es schon immer die Trennung zwischen Eingabe-Verarbeitung-Ausgabe. In GUI-basierenden Systemen wird diese konzeptionelle Trennung über das Model-View-Controller [MVC01] Konzept realisiert.
Model: Diese Schicht ist die Repräsentation der Daten. Der Zustand kann über Methoden der Objekte verändert werden.
View: Die visuelle Aufbereitung der Daten übernimmt der View. Diese Schicht ist die Schnittstelle zum Benutzer
Controller: Diese Schicht definiert das Verhalten der Applikation. Sie ist für die Interaktion der Benutzer mit den Views und dem Model verantwortlich.
Abbildung in dieser Leseprobe nicht enthalten
Abbildung 8: Model-View-Controller Konzept [ROR02]
3.2.2. MVC Umsetzung in Rails
Durch den Befehl rails <appname> erstellt Rails eine vordefinierte Verzeichnisstruktur.
Abbildung in dieser Leseprobe nicht enthalten
Abbildung 9: Rails Applikations-Verzeichnisstruktur
[...]
-
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen. -
Laden Sie Ihre eigenen Arbeiten hoch! Geld verdienen und iPhone X gewinnen.