Open Source im professionellen Einsatz
Linux-Magazin 11/2013
© Graham Oliver, 123RF.com

© Graham Oliver, 123RF.com

Ruby on Rails plus Angular.js

Flexible Unterlage

Das Webframework Ruby on Rails nimmt dem Entwickler viel Arbeit ab und lässt sich doch weitgehend anpassen. In der Beispielanwendung liefert es lediglich die Daten im Json-Format, das Anzeigen im Browser übernimmt die Javascript-Bibliothek Angular.js.

1067

Ruby on Rails ist ein Webframework auf Basis der Programmiersprache Ruby. Im Jahr 2004 hat es der dänische Entwickler David Heinemeier Hansson erstmals als Open Source veröffentlicht, inzwischen liegt die kurz auch Rails [1] genannte Software in der frisch gebackenen Version 4 vor.

Rails verspricht die Entwicklung von Datenbank-gestützten Webanwendungen stark zu beschleunigen. Zusammen mit dem Python-Framework Django begründete es eine neue Klasse von sehr kompletten Frameworks, zu denen zum Beispiel auch das PHP-Framework Symfony zu zählen ist, die dem Entwickler an vielen Stellen Arbeit abnehmen, typische Aufgaben mit Generatoren und anderen Konstrukten automatisieren und es einfach machen, Best Practices der Webentwicklung zu folgen.

Der Programmierer

Der Code stammt von Daniel Harrington https://github.com/rubiii. Er ist freiberuflicher Entwickler in Hamburg und arbeitet aktuell vorwiegend mit Ruby und Javascript.

Über seine nun bald zehnjährige Geschichte hat Rails zahlreiche Trends in der Webentwicklung mitgeprägt oder zumindest früh aufgegriffen. So sind etwa Prototype.js und Script.aculo.us, die als Vorgänger von Bibliotheken wie Jquery gelten können, im Rails-Umfeld entstanden. Rails war zudem eines der ersten Frameworks, die es dem Entwickler leicht gemacht haben, Webseiten mit Ajax-Funktionen anzureichern.

Rails nutzt dabei die Sprachmittel von Ruby sehr geschickt, um dynamisch zur Laufzeit Informationen zur Verfügung zu stellen, die in anderen Umgebungen bereits zur Entwurfszeit in Code gegossen werden.

Die Anwendung

Eine laufende Version der gelösten Aufgabe (Abbildung 1) findet sich unter [2]. Der Quellcode liegt unter [3] und lässt sich, sofern Ruby 2.0.0 installiert ist, recht einfach auch lokal betreiben. Eine genaue Beschreibung der weiteren Abhängigkeiten ist in der Readme-Datei im Quelltext nachzulesen.

Abbildung 1: Die Beispielanwendung verwendet einen Schieberegler (Slider) zur Datumseingrenzung und läuft auf der Plattform Heroku.

Eine typische Rails-Anwendung folgt im Wesentlichen einer eigenen Interpretation des allgegenwärtigen Model-View-Controller-Pattern (MVC). Die Modelle sind in der Regel so genannte »ActiveRecord« -Objekte, die mit Hilfe von Introspektion auf die Datenbank ohne zusätzlichen Code aus den Datenbankspalten Attribute und Methoden generieren.

Da es bei den vorgegebenen Daten um Festivitäten – neudeutsch Events – geht, liegt es nahe, ein Event-Model zu bauen. Es lässt sich, zusammen mit einer Migration, die das Datenbankschema anlegt, über einen Kommandozeilenaufruf generieren (hier nur ausschnittweise):

$ rails generate model Event source_id:string area:text description:textstreet:string[...]

Der Generator produziert drei Dateien: das etwas anämische Model (die Klasse »Event« ), einen vorerst ebenso spartanischen Test namens »EventTest« und die eben erwähnte Migration (Listing 1).

Listing 1

Datenbank-Migration

01 # 20130903183431_create_events.rb
02 class CreateEvents < ActiveRecord::Migration
03   def change
04     create_table :events do |t|
05       t.string :source_id
06       t.text   :area
07       t.text   :description
08       t.string :street
09       t.string :zip_code
10       t.date   :starts_at
11       t.date   :ends_at
12       t.text   :period
13       t.text   :host
14       t.string :email
15       t.string :website
16       t.text   :note
17       t.timestamps
18     end
19
20     add_index :events, :source_id
21   end
22 end

Datenbank-Migrationen

Migrationen in Rails sind möglichst Datenbank-agnostische Dateien, die in Ruby-Code beschreiben, wie das Schema der Datenbank zu ändern ist. Da diese Migrationen versioniert sind, kann man mit ihnen eine Datenbank automatisiert auf den aktuellen Stand bringen. Dafür ist eine Rake-Task zuständig. Rake [4] ist das leistungsfähige Ruby-Äquivalent zu Make und dient für allerlei Automatisierungen. Das Kommando »rake db:migrate« migriert das Datenbankschema auf den neuesten Stand.

Um die Daten in die Datenbank zu importieren, existiert eine weitere Rake-Task, die allerdings selbst gebaut ist: »rake workers:import« ruft die Daten alle auf einmal vom Berlin.de-Server ab, übersetzt die Attribute in die Datenstruktur für die Event-Klasse und legt dann je nach Stand der Datenbank neue Events an oder aktualisiert alte. Eine solche Task lässt sich per Cron regelmäßig ausführen. Die Task selbst ruft eigentlich nur eine Methode einer Klasseninstanz auf (Listing 2)

Listing 2

Import-Task

01 namespace :workers do
02   desc 'Import events from source'
03   task :import => :environment do
04     ImportWorker.new.run
05   end
06 end

Der »ImportWorker« liegt im Verzeichnis »app/workers/« . Dies ist kein Standardverzeichnis, Rails lädt jedoch automatisch alle Dateien, die in Unterverzeichnissen von »app/« liegen. Der Worker holt in einem Rutsch mit Hilfe der Bibliothek HTTPClient [5] die Inhalte vom Berlin.de-Server, benutzt Rubys Json-Bibliothek, um das ganze zu parsen, und schreibt dann, Event für Event, die Inhalte in die Datenbank. Hierzu gibt es eine Mapping-Methode, die die Feldnamen in den Json-Daten in Datenbankattribute übersetzt, sowie eine »upsert_event()« -Methode, die ein Event entweder anlegt oder aktualisiert (Listing 3).

Listing 3

ImportWorker

01 class ImportWorker
02   [...]
03   def map_to_event_hash(data)
04     {
05       source_id:   data['id'],
06       area:        data['bezirk'],
07       description: data['bezeichnung'],
08       street:      data['strasse'],
09       zip_code:    data['plz'],
10       starts_at:   Date.parse(data['von']),
11       ends_at:     Date.parse(data['bis']),
12       period:      data['zeit'],
13       host:        data['veranstalter'],
14       email:       data['mail'],
15       website:     data['www'],
16       note:        data['bemerkung']
17     }
18   end
19
20   def upsert_event(source_id, attributes)
21     Event.where(source_id: source_id)
22       .first_or_initialize
23       .update_attributes(attributes)
24   end
25 end

Die Methode »upsert_event« zeigt sehr schön die Benutzung der Objekt-Abstraktionsschicht »ActiveRecord« : Unter der Haube von »ActiveRecord« arbeitet eine ausgereifte Bibliothek für den Umgang mit relationaler Algebra. Hier ist der Fall eindeutig – die »where()« -Methode erzeugt eine SQL-»WHERE« -Klausel in der Form »WHERE source_id = ?« .

Das »first_or_initialize« liefert entweder den ersten Treffer der Abfrage zurück oder aber ein leeres Objekt, wenn kein Treffer gefunden, das Event also noch nicht importiert wurde. Die Methode »update_attributes« aktualisiert die Attribute und speichert das Ganze in der Datenbank.

Die nächste Schicht im Rails-MVC-Modell ist der Controller, der den HTTP-Request entgegennimmt und beantwortet. Wie Listing 4 zeigt, ist er recht simpel. Den Request nimmt die »index« -Methode entgegen. Das »respond_to« legt fest, dass dieser Controller nur auf Anfragen reagiert, die Json verlangen. In der Index-Methode liest »Event.all« die ganze Events-Tabelle aus. Die Berliner Datenquelle liefert derzeit knapp 300 Events, sodass sich die Rechenarbeit in Grenzen hält. Das »respond_with()« sorgt dafür, dass die Daten im richtigen Datentypus ausgegeben werden. »ActiveRecord« bringt für Json und XML bereits eigene Methoden zur Konvertierung mit, sodass der Entwickler hier der Einfachheit halber die rohen Daten aus der Datenbank ausgeben darf.

Listing 4

Controller

01 class EventsController < ApplicationController
02
03   respond_to :json
04
05   def index
06     respond_with(Event.all)
07   end
08
09 end

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 5 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

Linux-Magazin kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • Rubymine 6.3. mit Angular-JS- und Vagrant-Unterstützung

    Das Unternehmen Jetbrains hat seine proprietäre Ruby-Entwicklungsumgebung Rubymine in Version 6.3 mit neuen Features veröffentlicht.

  • Ruby on Rails 5.0 ist da

    Mit Action Cable bringt Ruby on Rails 5.0 ein brandneues Framework mit, das sich um Websockets kümmert. Und das ist nicht die einzige Neuerung in der nach sechs Monaten Arbeit veröffentlichten Rails-Neuauflage.

  • Bewertung

    Viele Wege führen ans Ziel, das gilt auch für die Wahl von Software für die Website. Wer aber zuerst ankommt und unterwegs Angenehmes erlebt, ist klar im Vorteil. Der Versuch einer Podest-Zuweisung.

  • Vexor, ein Continuous-Integration-Server

    Ein neuer Server für Continuous Integration (CI) namens Vexor bietet an, Anwendungen in Ruby, Scala und Clojure zu testen.

  • Kod.io: Programmiersprachen und Kulturen in Linz

    Auf der Konferenz Kod.io im oberösterreichischen Linz haben sich rund 300 Entwickler aus vielen Nationen über zeitgemäße Softwareentwicklung in Ruby, Javascript, Python, C# und weiteren Sprachen ausgetauscht.

comments powered by Disqus

Ausgabe 11/2017

Digitale Ausgabe: Preis € 6,40
(inkl. 19% MwSt.)

Stellenmarkt

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.