Websiteentwicklung: Ruby on Rails/ Druckversion
Aus Wikibooks
[Bearbeiten] Vorwort
Lieber Leser, liebe Leserin,
Ruby on Rails (RoR) ist ein mächtiges Framework für die Entwicklung von Webapplikationen. Dieses Buch bietet einen schnellen Einblick in RoR - wenn man sich mit HTML, CSS, Javascript und einer serverseitigen Sprache wie z.B. PHP schon auskennt.
Die Beispiel-Applikation, die im Laufe des Buches entwickelt wird, ist auch online:
Es gibt noch ein wesentlich umfangreicheres Wikibook Ruby on Rails für die Vertiefung.
Viel Spaß beim Lernen und Ausprobieren!
Was ist Ruby on Rails
"Ruby on Rails" besteht aus zwei Teilen: Ruby ist eine Open Source Skriptsprache, ähnlich wie Perl oder Python. Ruby kann in verschiedenen Bereichen verwendet werden. Rails ist ein umfangreiches Web-Framework für diese Sprache.
[Bearbeiten] Was zeichnet Ruby aus?
- dynamische Sprache
- hoch-dynamische Community
[Bearbeiten] Was zeichnet Rails aus?
[Bearbeiten] DRY - Don't Repeat Yourself
Rails versucht Code-Verdopplungen zu vermeiden. Man schreib immer sehr kurzen Code, und kann viel damit erreichen.
[Bearbeiten] Convention over Configuration
Rails hat viele, viele Konventionen. z.B. wo die Dateien gespeichert werden, wie die Datenbanken heißen, u.s.w.
Wenn man sich an die Konventionen hält ist das Leben einfach, man hat wenig Arbeit, und alles funktioniert. (Wenn man sich nicht an die Konventionen halten will, kann man sich das Leben beliebig schwierig machen.)
[Bearbeiten] Model - View - Controller
Die Idee von Model - View - Controller wird in vielen Web-Applikationen verwendet. Es handelt sich um einen Pattern, der schon lange Zeit für die Erstellung von Benutzer-Interfaces verwendet wird.
Was MVC für ein eine Web-Applikation bedeutet, sei an einem konkreten Beispiel erklärt: Wir wollen ein Kursverwaltungssystem programmieren, in dem Leute Kurse buchen können.
- Das Model
- ist ein Modell unseres Problemfelds. Für die Kursverwaltung brauchen wir also Kurse, User, Buchungen, etc. Diese sind in einer Datenbank gespeichert, in Tabellen namens kurse, user, buchungen. Für die Programmierung werden diese Datenbank-Tabellen auf Klassen umgelegt: in der Kurs-Klasse gibt es mehrere Kurs-Objekte. Dies erfolgt automatisch; wir brauchen - im Idealfall - keine einzige Zeile SQL zu schreiben.
- Die View
- behandelt alle Probleme der Darstellung. Die View ist also eine Datei die hauptsächlich HTML, eventuell CSS und Javascript. Ein bisschen Ruby-Code sorgt für die Details der Anzeige, z.B. eine Schleife über alle User oder eine bedingte Anzeige: nur zukünftige Kurse.
- Der Controller
- nimmt die Daten aus der URL und/oder die Parameter entgegen, ruft das richtige Modell auf, bereitet die richtigen Daten für die View vor... er hält also alles zusammen. Achtung: der Controller kann weder HTML noch SQL enthalten - das ist nicht seine Aufgabe!
[Bearbeiten] Tests
Rails unterstüzt Dich beim Schreiben von automatisierten Tests. Damit kann man sehr gut Test Driven Development (TDD) machen: erst den Test schreiben, dann erst das Programm dazu.
[Bearbeiten] Wer verwendet Ruby on Rails?
Twitter, Scribd und Slideshare sind wohl die berühmtesten Rails-Applikationen. In Europa verwendet XING (in Hamburg) Rails.
[Bearbeiten] Warum sollte ich 'nicht' RoR verwenden?
Für sehr kleine Web-Applikationen ist der Einsatz eines großen Frameworks wie Rails nicht sinnvoll.
Die Sprache Ruby
Ruby ist eine Skriptsprache.
[Bearbeiten] Der Interpreter
Du kannst den Ruby-Interpreter direkt aufrufen und Befehle testen:
D:\>irb
irb(main):001:0> 1+1
=> 2
irb(main):002:0> exit
[Bearbeiten] Ein einfaches Skript
Ruby-Programme speichert man in Dateien mit der Endung .rb Hier ein einfaches Programm, nenne die Datei hallo.rb
puts "Hallo Welt"
Nun kannst Du das Programm auf der Kommendozeile starten:
d:/>ruby hallo.rb hallo Welt
Eine Ruby on Rails Applikationen von Außen
Woran erkennt man eine Rails-Applikation?
Betrachten wir dazu die Demo-Site von Redmine, einer Projektmanagement-Applikation die in Ruby geschreiben ist.
[Bearbeiten] URLs
Die URLs eine Rails-Applikation haben meist keine Endung, oft keine Parameter. Statt dessen ist die Information direkt im Pfad:
http://demo.redmine.org/projects/learnrails/boards http://demo.redmine.org/projects/learnrails/boards/453 http://demo.redmine.org/projects/learnrails/boards/454 http://demo.redmine.org/projects/learnrails/boards/455
Dahinter stecken aber nicht Ordner in einem Filesystem, sondern diese URL wird auf Controller, Actions und Parameter umgeschreiben. der Kommandozeilen-Befehl rake routes zeigt die Regeln dafür an:
GET /projects/:project_id/boards {:controller=>"boards", :action=>"index" }
GET /projects/:project_id/boards/:id {:controller=>"boards", :action=>"show" }
Die action index zeigt dabei eine Liste (der Boards) an, die action show zeigt ein einzelnes Board an.
[Bearbeiten] Für fortgeschrittene ProgrammiererInnen
[Bearbeiten] REST
Diese Struktur der URLs ist aber nur der offensichtlichste Teil eines tiefergehenden Plans. Nicht nur GET, sondern auch die anderen HTTP-Methoden werde verwendet:
GET /dings {:controller=>"dings", :action=>"index" } # zeigt eine liste aller dinge
POST /dings {:controller=>"dings", :action=>"create" } # erzeugt ein neues ding (id steht noch nicht fest)
GET /dings/new {:controller=>"dings", :action=>"new" } # zeigt ein Eingabeformular für ein ding
GET /dings/:id/edit {:controller=>"dings", :action=>"edit" } # zeigt ein Bearbeitungsformular für ein bestehendes ding
GET /dings/:id {:controller=>"dings", :action=>"show" } # zeigt ein bestimmtes ding an
PUT /dings/:id {:controller=>"dings", :action=>"update" } # speichert/ändert ein bestehenden ding
DELETE /dings/:id {:controller=>"dings", :action=>"destroy"} # löscht ein ding
Das ist die Grundstruktur die für verschiedene Ressourcen immer wieder gleiche verwendet werden kann. Die Idee dahinter ist REST[1].
[Bearbeiten] Webservice
Mit der Endung .xml kann die Rails-Applikation auch XML als Output liefern:
GET /dings.xml POST /dings.xml GET /dings/new.xml GET /dings/:id/edit.xml GET /dings/:id.xml PUT /dings/:id.xml DELETE /dings/:id.xml
Damit bietet die Web-Applikation automatisch eine REST Webservice Schnittstelle an. Das kann man für AJAX verwenden oder als API für die Applikation.
(Oder man ignoriert es erst mal.)
Erste Rails App
[Bearbeiten] Die Rails Applikation erzeugen
Bei der Arbeit mit Ruby on Rails spielt nicht nur der eigentliche Source-Code, sondern auch die Kommandozeile eine wichtige Rolle. Schon der erste Schritt passiert auf der Kommandozeile: um die Grund-Struktur der Rails-Applikation zu erzeugen wird der rails-Befehl aufgerufen:
rails -d mysql hallowelt cd hallowelt
Damit wird eine Reihe von Ordnern und Dateien erzeugt:
Die Kommandozeile wird auch weiterhin (mehrfacht) gebraucht.
Der Webserver wird auf der Kommandozeile gestartet:
ruby script\server
und auch bei vielen weiteren Schritten brauchen wir noch (ein neue) Kommandozeile um verschiedene Skripts im Ordner script aufzurufen (script\server ist nicht das einzige) oder um rake-Befehle abzusetzen.
rake db:migrate
[Bearbeiten] Scaffolding
Nach dem Model-View-Controller Prinzip müssen wir für unsere Datenbank der Hallo-Welt Meldungen
- eine Tabelle in der Datenbank anlegen
- ein Model erzeugen
- einen Controller (mit eventuell verschiedenen Actions) erzeugen
- für die Actions jeweils Views erzeugen
Rails hilft uns, das Alles auf einmal zu machen.
[Bearbeiten] Scaffold erzeugen
Dazu verwenden wir das generate-script und erzeugen damit ein scaffold - ein Gerüst:
ruby script\generate scaffold hallo von:string meldung:text farbe:string
Das erste Argument hallo ist der Name des Modells, danach folgen die Eigenschaften und Datentypen des Modells.
In diesem Fall will ich zu jedem "hallo" abspeichern: von dem die Meldung ist, den Text der Meldung und welche Farbe die Meldung haben soll.
Nun müssen wir noch die Datenbank-Tabelle wirklich anlegen, das geschieht mit
rake db:migrate
[Bearbeiten] Die Datenbank
Ein Blick in die Datenbank zeigt: es wurde ein Tabelle hallos erzeugt. Also Name für das Modell hatten wir hallo gewählt, rails hat automatisch die Mehrzahl für die Bezeichnung der Tabelle gewält.
Ein Primärschlüssel namens id und die beiden Felder created_at und updated_at wurden ebenfalls automatisch angelegt.
Die Datentypen wurden auch von Ruby auf Datenbank übersetzt: aus string wurde varchar(255).
[Bearbeiten] Das Modell in app/models/hallo.rb
Die Klassen-Datei für das Modell wurde angelegt, ist aber noch leer.
Hier könnten wir Methoden eintragen die die innere Logik des Modells abbilden.
Für die Validierung der Daten bietet Rails viele Praktische Kurz-Schreibweisen an. Wenn wir z.B. sicherstellen wollen, dass als Farbe nur ein HTML-Farbcode wie #FF0033 gespeichert werden kann, dann reicht dazu eine Zeile im Modell:
validates_format_of :farbe, :with => /^#......$/, :message => "nur Farb-Code mit # und 6 Stellen (hexadezimal) erlaubt"
Das erste Argument ist der Name der Spalte / der Eigenschaft, mit dem benannten Argument :with gibt man eine Regular Experssion zur Überprüfung an, und mit :message eine passende Fehlermeldung.
[Bearbeiten] Der Controller in app/controllers/hallos_controller.rb
Diese Datei ist umfangreich: sie enthält 7 vorgefertigte Actions:
- index - listet alle Meldungen auf
- show - zeigt eine bestimmte meldung an (ID notwendig!)
- new - zeigt ein Eingabeformular für eine neue Meldung an (weiter bei create)
- edit - zeigt eine Meldung in einem Bearbeitungsformular an (ID notwendig!, weiter bei update)
- create - erzeugt eine neue Meldung
- update - verändert eine Meldung
- destroy - löscht eine Meldung (ID notwendig!)
Betrachten wir die einfachste Action: show zeigt eine bestimmte Meldung an. Beim Aufruf dieser Action muss eine id als Parameter übergeben werden:
def show @hallo = Hallo.find(params[:id]) end
Über den Parameter id wird der Datensatz Hallo als Objekt geladen und in der Instanzvariable @hallo des Controllers gespeichert. Alles weitere geschieht automatisch: die Darstellung erfolgt über die Datei views/hallos/show.html.erb
Die Action funktioniert aber nicht nur für den Fall, dass Sie HTML als Output liefern soll. Auch XML als Output ist möglich. Dafür sind 4 weiter Zeile Code notwendig:
def show
@hallo = Hallo.find(params[:id])
respond_to do |format|
format.html
format.xml { render :xml => @hallo }
end
end
[Bearbeiten] Routing - von der URL zur Action
Mit dem Kommandozeilen-Befehl rake routes kann man sehen wie URLs, Controller, Actions zusammen hängen. Dies wird in der Datei config/routes.rb festgelegt, wurde aber durch das Scaffolding automatisch erledigt. Hier der Output von rake routes:
hallos GET /hallos(.:format) {:action=>"index", :controller=>"hallos"}
POST /hallos(.:format) {:action=>"create", :controller=>"hallos"}
new_hallo GET /hallos/new(.:format) {:action=>"new", :controller=>"hallos"}
edit_hallo GET /hallos/:id/edit(.:format) {:action=>"edit", :controller=>"hallos"}
hallo GET /hallos/:id(.:format) {:action=>"show", :controller=>"hallos"}
PUT /hallos/:id(.:format) {:action=>"update", :controller=>"hallos"}
DELETE /hallos/:id(.:format) {:action=>"destroy", :controller=>"hallos"}
Ganz links ist für manche Routes ein Name angegeben, den man innerhalb von Views und Controllern verwenden kann. In der zweiten Spalte finden Sie die HTTP Methode, anschießend die URL und zuletzt die Kombination von Controller und Action die hier aufgerufen werden.
Die route mit dem namen hallo (3.von unten) bedeutet also: Wenn mit GET ein Aufruf von http://localhost:3000/hallos/14 erfolgt, dann wird der Controller hallos mit Action show aufgerufen. Wo :id steht kann also eine Zahl eingesetzt werden. Wo :format steht kann xml eingefügt werden: Wenn mit GET ein Auftruf von http://localhost:3000/hallos/14.xml erfolgt, dann wird der Controller hallos mit Action show aufgerufen, er soll dann XML als Output produzieren.
Nun wäre ein guter Zeitpunkt die Appliation auszuprobieren und ein paar Meldungen einzufügen, wieder zu verändern oder zu löschen
[Bearbeiten] Die Views in app/views/hallos/*.html.erb
Vier Views wurden automatisch angelegt:
- index.html.erb - listet alle Meldungen auf
- show.html.erb - zeigt eine bestimmte meldung an (ID notwendig!)
- new.html.erb - zeigt ein Eingabeformular für eine neue Meldung an (weiter bei create)
- edit.html.erb - zeigt eine Meldung in einem Bearbeitungsformular an (ID notwendig!, weiter bei update)
Das Format der Views ist Embedded Ruby (Endung .erb). Eine View besteht hauptsächlich aus HTML, mit <% ... %> kann Ruby eingebettet werden das ausgeführt wird. Mit <%= ... %> kann Ruby eingebettet werden das Output liefert. Dabei werden hauptächlich die Instanz-Variablen des Controllers verwendet.
Die View show.html.erb zeigt eine Meldung an.
<p>
<b>Von:</b>
<%=h @hallo.von %>
</p>
<p>
<b>Meldung:</b>
<%=h @hallo.meldung %>
</p>
<p>
<b>Farbe:</b>
<%=h @hallo.farbe %>
</p>
<%= link_to 'Edit', edit_hallo_path(@hallo) %> |
<%= link_to 'Back', hallos_path %>
Die beiden letzten Zeilen erzeugen zwei Links. Das erste Argument von link_to ist der Link-Text. Das zweite Argument ist die URL. Hier werden Methoden aufgerufen, die automatisch für alle benannten routes vorhanden sind (siehe rake routes).
Die route hallo braucht keine Parameter, mit hallo_path erhält man die URL ohne Hostnamen, mit hallo_url die vollständige URL.
Bei edit_hallo ist es etwas komplizierter: diese Route muss wissen, welches Objekt gemeint ist. Hier kann man als Argument entweder das ganze Objekt oder nur die id des Objekts übergeben. Auch hier gibt es wieder die Formen edit_hallo_path und edit_hallo_url.
Die Darstellung der Meldung können wir ganz verändern: Die Farbe wird wirklich als Farbe verwendet und nicht als Text angezeigt
<div class="meldung">
<p><%=h @hallo.von %> sagt:</p>
<blockquote style="color: <%= @hallo.farbe %>"><%=h @hallo.meldung %></blockquote>
</div>
<%= link_to 'Edit', edit_hallo_path(@hallo) %> |
<%= link_to 'Back', hallos_path %>
Verändern Sie auch index.html.erb so, dass die Farbe wirklich als Farbe verwendet wird! Achtung: in der index-View gibt es zwei Variablen: @hallos ist ein Array aller Meldungen, hallo ist die jeweils aktuelle Meldung.
[Bearbeiten] Eine neue Homepage einsetzen
Der hallo-Controller wäre ein sehr gut Homepage für unsere 'Hallo Welt' Applikation. Um das zu erreichen, muss man die Datei public\index.html löschen und in config/routes.rb folgende Zeile einfügen:
map.root :controller => "hallos"
Damit ist die erste Webapplikation in Ruby on Rails fertig.
Konfiguation und Datenbank
Wenn man ein Projekt mit
rails projektname
startet, speichert Rails die Daten in einer sqlite-Datenbank. Das ist besonders einfach: alle Daten sind in der Datei db/development.sqlite3 zu finden.
Wenn man das Projekt gleich mit
rails -d mysql projektname
startet wird statt dess mysql verwendet. Nun wollen wir uns näher mit der Konfiguration befassen und dabei lernen wie man ein laufendees Projekt auf ein mysql-Datenbank umstellt.
[Bearbeiten] Konfigurations-Dateien
Im Ordner config sind u.a. folgende Dateien zu finden:
- database.yml
- Konfiguration der Datenbanken für die verschiedenen Server
- routes.rb
- Konfiguation der URLs und ihrer Umrechnung auf Controller und Actions
- environment.rb
- weitere Konfiguration
- locales/en.yml
- Texte für die englische Version der Website (hier könnte man de.yml, it.yml, u.s.w. einfügen)
[Bearbeiten] Datenbank
Die Datei database.yml enthält normalerweise folgenden Code:
development:
adapter: sqlite3
database: db/development.sqlite3
pool: 5
timeout: 5000
#
test:
adapter: sqlite3
database: db/test.sqlite3
pool: 5
timeout: 5000
#
production:
adapter: sqlite3
database: db/production.sqlite3
pool: 5
timeout: 5000
Hier sehen wir dass in Rails von Anfang an drei verschiedene Server vorgesehen sind:
- development
- ist die Datenbank für die Entwicklung, wenn ich das Programm schreibe und ausprobiere
- test
- ist die Datenbank für die automatischen Tests. Diese Datenbank wird auch automatisch erzeugt und wieder gelöscht
- production
- ist die Datenbank für den Echt-Betrieb
Wenn ich mysql statt sylite verwenden will muss ich einerseits entsprechende Datenbanken in meinem MySQL Server anlegen und andererseits die Konfigurationsdate ändern. Hier ein Beispiel für das Projekt 'chor': (Achtung beim Kopieren dieses Codes: diese Konfigurationsdatei verträgt keine Tabulatoren und keine leerzeichen vor development, test, production!)
development:
adapter: mysql
encoding: utf8
reconnect: false
database: chor_development
pool: 5
username: root
password:
host: localhost
#
test:
adapter: mysql
encoding: utf8
reconnect: false
database: chor_test
pool: 5
username: root
password:
host: localhost
#
production:
adapter: mysql
encoding: utf8
reconnect: false
database: chor_production
pool: 5
username: root
password:
host: localhost
Die Konvention, and den Applikationsnamen mit Unterstrich etwas anzuhängen um den Datenbanknamen zu erzeugen hat eine angenehme Nebenwirkung: in phpmyadmin werden die Datenbanken gruppiert:
Datenbank und Model
Wie arbeiten Datenbank und Model zusammen?
[Bearbeiten] Datenbank verändern mit Migrations
[Bearbeiten] Die Problemstellung
Bei Web-Applikationen tritt folgendes Problem auf: im Laufe der Entwicklung ändert sich das Datenbank-Schema. Gleichzeitig ist die Applikation aber schon im Echt-Betrieb, man kann die Produktions-Datenbank nicht einfach löschen und von Grund auf neu bauen.
Es ist also notwendig, die Veränderungs-Schritte der Datenbank zu speichern, und auf allen Servern (verschiedene Entwicklungs-Rechner, Test, Produktion) in der gleichen Reihenfolge nachzuvollziehen.
Ruby on Rails bietet dafür eine Lösung: Migrations.
Eine Migration ist dabei ein Schritt der Veränderung - wobei dieser Schritt immer in beide Richtungen definiert ist.
Im Ordner /db/migrations/ sind die einzelnen Migrations gespeichert.
Nach der Erzeugung des scaffolds für hallo sieht das z.B. so aus:
20090829142637_create_hallos.rb
Diese Datei enthält das Anlegen der Tabelle für das Model Hallo:
class CreateHallos < ActiveRecord::Migration
def self.up
create_table :hallos do |t|
t.string :von
t.text :meldung
t.string :farbe
t.timestamps
end
end
def self.down
drop_table :hallos
end
end
[Bearbeiten] Eine Migration erstellen
Mit dem Kommandozeilen-Befehl
rake db:migration
werden jeweils alle neuen Migrations ausgeführt. Mit
rake db:rollback
kann der letzte Schritt rückgängig gemacht werden. Welcher Migrations-Schritt bereits angewandt wurde wird in der Datenbank salbst gespeichert, in der Tabelle schema_migrations
Wenn man die Datenbank verändern will - zum Beispiel um eine neue Spalte in die Tabelle einzufügen - so kann man selbst eine migration erzeugen:
ruby script/generate migration AddWiederholungToHallo wiederholung:integer
Aus der Namens-Konvention erzeugt der Generator gleich einen guten Entwurf für die Migration:
class AddWiederholungToHallo < ActiveRecord::Migration
def self.up
add_column :hallos, :wiederholung, :integer
end
def self.down
remove_column :hallos, :wiederholung
end
end
[Bearbeiten] Was noch zu tun ist
| Dazu gibt es einen Rails Guide [2] Migrations |
Nach dem Hinzufügen oder Löschen von Spalten aus der Tabelle muss das Model nicht verändert werden! Die Spalten werden automatisch als Attribute des Objekts übernommen. Der Controller muss meist auch nicht verändert werden.
Nur die Views (Eingabemasken, Anzeige des Objekts) müssen verändert werden!
[Bearbeiten] Daten lesen und speichern mit dem Model
Wir arbeitet das Model mit der Datenbank zusammen? Das werden wir nun interaktiv erforschen
[Bearbeiten] Daten Suchen und Finden
Es gibt eine interaktive Shell für Rails. Gestartet wird sie mit
ruby script\console
Nun kann man ruby-befehle eintippen und sieht sofort das Ergebnis.
>> Hallo.find(1) => #<Hallo id: 1, von: "Brigitte", meldung: "Hallo Welt, es freut mich sehr Dich zu sehen!", farbe: "#FF0000", created_at: "2009-08-29 14:28:54", updated_at: "2009-08-29 14:28:54">
Die Klasse Hallo hat (wie jedes Klasse des Models) eine Methode find. Mit find(1) suche ich nach dem Objekt das in der Datenbank die id=1 hat.
Mit find(:all) suche ich nach allen Objekten. Das gibt viel output (hier gekürzt!)
>> Hallo.find(:all) => [#<Hallo id: 1, von: "Brigitte">, #<Hallo id: 2, von: "Karin">, #<Hallo id: 3, von: "Hilmar">]
[Bearbeiten] Daten anlegen
Hier kann man auch neue Objekte anlegen:
>> h = Hallo.new => #<Hallo id: nil, von: nil, meldung: nil, farbe: nil, created_at: nil, updated_at: nil> >> h.von = "Tippse" => "Tippse" >> h.meldung = "Auch ohne das Web kann ich einfügen" => "Auch ohne das Web kann ich einf\201gen" >> h => #<Hallo id: nil, von: "Tippse", meldung: "Auch ohne das Web kann ich einf\201gen", farbe: nil, created_at: nil, updated_at: nil>
das Objekt existiert derzeit nur im Hauptspeicher, im laufenden Programm - es ist noch nicht in der Datenbank gespeichert. (Deswegen hat es auch noch keine id). mit save kann ich versuchen das Objekt zu speichern:
>> h.save => false
Der Rückgabewert false bedeutet: das Speichern hat nicht funktioniert. Warum? Weil die Farbe nicht gespeichert werden kann, ich habe ja eine Validierung auf dem Farb-Feld Programmiert:
# im Model validates_format_of :farbe, :with => /^#......$/, :message => "nur Farb-Code mit # und 6 Stellen (hexadezimal) erlaubt"
Also muss ich die Farbe korrekt setzen und kann dann speichern:
>> h.farbe="#00FF00" => "#00FF00" >> h.save => true
Danach hat h auch eine id, und werte in created_at und updated_at:
>> h => #<Hallo id: 7, von: "Tippse", meldung: "Auch ohne das Web kann ich einf\201gen", farbe: "#00FF00", created_at: "2009-08-31 11:46:06", updated_at: "2009-08-31 11:46:06">
Controller und View
Views, Partials und Layouts
| Dazu gibt es einen Rails Guide [4] Layouts and Rendering |
Beim Schreiben der View ist Dir vielleicht aufgefallen, dass nirgendwo ein head oder body zu lesen ist. Diese Teile der Webseite, die für die einzelnen Seiten der Applikation gleich sind, werden nicht in der View selbst gespeichert:
[Bearbeiten] Layout
Für eine einfache Webapplikation brauchen wir nur ein Layout: wir können das vorhandene Layout hallos.html.erb umbenennen auf application.html.erb.
Die vom Scaffold erstellte Datei enthält viel HTML, und an zwei Stellen Ruby:
<title><%= controller.controller_name %> : <%= controller.action_name %></title> <%= stylesheet_link_tag 'scaffold' %>
Hier wird im titel der Namen des Controllers angezeigt und ein Stylesheet geladen.
[Bearbeiten] Partials
[Bearbeiten] Einfaches Partial
In den Views edit.html.erb und new.html.erg wird genau das selbe Formular verwendet. Dieses Formular wollen wir nun in ein Partial auslagern. In beiden Views steht nur noch
<%= render :partial => "form" %>
Achtung: damit wird die Datei _form.html.erb geladen! (Beachte den Unterstrich!)
Das Partial selbst enthält einfach den Code mit dem Formular.
Damit new und edit verschiedene Beschriftungen beim Submit-Button haben kann man eine Variable an das Partial übergeben:
<%= render :partial => "form", :locals => { :button_label => "Meldung Speichern" } %>
<%= render :partial => "form", :locals => { :button_label => "Wieder Speichern" } %>
Im Partial stehen die Variablen zur Verfügung:
<%= f.submit button_label %>
[Bearbeiten] Partial mit Schleife
Die Darstellung der hallo-Meldungen in show und index können wir auch vereinheitlichen. Wir erzeugen ein Partial _meldung.html.erb', das eine einzelne Meldung darstellt. Diese Meldung ist in der Varialbe meldung zu finden - das ergibt sich aus dem Dateinamen des Partials:
<div class="meldung">
<p><%=h meldung.von %> sagt:</p>
<blockquote><%=h meldung.meldung %></blockquote>
</div>
Dieses Partial kann nun in der View von show einfach aufgerufen werden:
<%= render :partial => "meldung", :object => @hallo %>
In der View von index war bisher eine Schleife über das Array @hallos nötig. Dies entfällt mit dem Aufruf des Partials mit dem Argument :collection:
<%= render :partial => "meldung", :collection => @hallos %>
[Bearbeiten] Absolute Links und URLs vermeiden
Wir haben schon verschiedene Methoden kennen gelernt, wie wir vermeiden können fixe URLs zur programmieren:
<%= link_to 'Edit', edit_hallo_path(@hallo) %> | <%= link_to 'Back', hallos_path %> <%= stylesheet_link_tag 'scaffold' %>
Analoges gibt es auch noch für Bilder:
<%= image_tag("rails.png") %>
Für Javascript gibt es auch eine Standard-Einstellung, damit wird normalerweise Prototype und Scriptaculous geladen:
<%= javascript_include_tag :defaults %>
Weitere Quellen
- Auf Englisch: Rails Guides
- Auf Englisch: Buch Rails for PHP Developers
[Bearbeiten] Verwendete Quellen
- ↑ Tilkov(2007): A Brief Introduction to REST. In: InfoQ.
- ↑ Rails Guide Migrations
- ↑ Rails API ActiveRecord Migration
- ↑ Rails Guide Layouts and Rendering
- ↑ Rails API AssetTagHelper





