Websiteentwicklung: Ruby on Rails/ Druckversion

Aus Wikibooks
Wechseln zu: Navigation, Suche
Druckversion des Buches Websiteentwicklung: Ruby on Rails
  • Dieses Buch umfasst derzeit etwa 19 DIN-A4-Seiten einschließlich Bilder (Stand: 1.September 2009).
  • Wenn Sie dieses Buch drucken oder die Druckvorschau Ihres Browsers verwenden, ist diese Notiz nicht sichtbar.
  • Zum Drucken klicken Sie in der linken Menüleiste im Abschnitt „Drucken/exportieren“ auf Als PDF herunterladen.
  • Mehr Informationen über Druckversionen siehe Hilfe:Fertigstellen/ PDF-Versionen.
  • Hinweise:
    • Für einen reinen Text-Ausdruck kann man die Bilder-Darstellung im Browser deaktivieren:
      • Internet-Explorer: Extras > Internetoptionen > Erweitert > Bilder anzeigen (Häkchen entfernen und mit OK bestätigen)
      • Mozilla Firefox: Extras > Einstellungen > Inhalt > Grafiken laden (Häkchen entfernen und mit OK bestätigen)
      • Opera: Ansicht > Bilder > Keine Bilder
    • Texte, die in Klappboxen stehen, werden nicht mit ausgedruckt.
    • Die Funktion „Als PDF herunterladen“ kann zu Darstellungsfehlern führen.


('Dies ist die Druckversion, mit allen Inhalten auf einer Webseite. Für das Lesen Online ist die Version in einzelnen Seiten besser geeignet')


[Bearbeiten] Vorwort

Das Logo von Rails

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:

gesamter code als zip-Datei zum Download
hallo welt applikation auf heroku


Es gibt noch ein wesentlich umfangreicheres Wikibook Ruby on Rails für die Vertiefung.

Viel Spaß beim Lernen und Ausprobieren!


Inhaltsverzeichnis


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.


Das Logo von Ruby

[Bearbeiten] Was zeichnet Ruby aus?

  • dynamische Sprache
  • hoch-dynamische Community
Das Logo von Rails

[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.

Rails model view controller.png

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.

http://demo.redmine.org/

[Bearbeiten] URLs

Die URLs einer 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 werden 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:

Rails folders.png

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

  1. eine Tabelle in der Datenbank anlegen
  2. ein Model erzeugen
  3. einen Controller (mit eventuell verschiedenen Actions) erzeugen
  4. 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.

Rails tabelle.png

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 Applikation 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 &lt% ... %> 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 laufendes 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:

Rails dbs in phpmyadmin.png


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

Rails schema migrations.png

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

Rails Guide Dazu gibt es einen Rails Guide [2] Migrations
Rails Guide Siehe dazu die Rails API[3] ActiveRecord Migration


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

Rails Guide 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:

Rails layouts views partials.png



[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.erb 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

Rails Guide Siehe dazu die Rails API[5] AssetTagHelper

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


[Bearbeiten] Verwendete Quellen

  1. Tilkov(2007): A Brief Introduction to REST. In: InfoQ.
  2. Rails Guide Migrations
  3. Rails API ActiveRecord Migration
  4. Rails Guide Layouts and Rendering
  5. Rails API AssetTagHelper
Meine Werkzeuge
Namensräume

Varianten
Aktionen
Navigation
Mitmachen
Werkzeuge
Drucken/exportieren