Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Geleitwort des Fachgutachters
Einleitung
1 Einführung
2 Installation
3 Erste Schritte
4 Einführung in Ruby
5 Eine einfache Bookmarkverwaltung
6 Test-Driven Development
7 Rails-Projekte erstellen
8 Templatesystem mit ActionView
9 Steuerzentrale mit ActionController
10 Datenbankzugriff mit ActiveRecord
11 E-Mails verwalten mit ActionMailer
12 Nützliche Helfer mit ActiveSupport
13 Ajax on Rails
14 RESTful Rails und Webservices
15 Rails mit Plug-ins erweitern
16 Performancesteigerung
17 Sicherheit
18 Veröffentlichen einer Rails-Applikation auf einem Server
Ihre Meinung?

Spacer
 <<   zurück
Ruby on Rails 2 von Hussein Morsy, Tanja Otto
Das Entwickler-Handbuch
Buch: Ruby on Rails 2

Ruby on Rails 2
geb., mit DVD
699 S., 39,90 Euro
Rheinwerk Computing
ISBN 978-3-89842-779-1
Online bestellenPrint-Version Jetzt Buch bestellen
* versandkostenfrei in (D) und (A)
Pfeil 5 Eine einfache Bookmarkverwaltung
  Pfeil 5.1 Rails-Projekt erstellen
  Pfeil 5.2 Weitere Views anlegen
  Pfeil 5.3 Layout
  Pfeil 5.4 Model
  Pfeil 5.5 CRUD - Create - Read - Update - Delete
  Pfeil 5.6 Fehlerbehandlung in Formularen
  Pfeil 5.7 Flash-Messages
  Pfeil 5.8 Refaktorisierung mit Helper und Partials
  Pfeil 5.9 Authentifizierung
  Pfeil 5.10 Routing
  Pfeil 5.11 RESTful Rails
  Pfeil 5.12 Darstellungsformate in RESTful Rails
  Pfeil 5.13 Ajax


Rheinwerk Computing - Zum Seitenanfang

5.4 Model  Zur nächsten ÜberschriftZur vorigen Überschrift

Bis jetzt haben wir unsere Bookmarks manuell über ein Array im Controller gesetzt. Das ist aber nicht komfortabel für die Eingabe von neuen Bookmarks und auch nicht sinnvoll für die Verwaltung von vielen Bookmarks, schon gar nicht, wenn sie in strukturierter Form, wie zum Beispiel Angabe von URL und Titel, vorliegen.

Abbildung  Model

Datenbank- konfigurationsdatei

Das heißt, wir möchten und sollten unsere Bookmarks in einer Datenbank verwalten. Bis jetzt haben wir aber noch keine Datenbank angelegt. In Rails wird die Verwaltung der Datenbank über eine Konfigurationsdatei database.yml im Verzeichnis config gesteuert:

Listing  config/database.yml

development:
  adapter: sqlite3
  database: db/development.sqlite3
  timeout: 5000

test:
  adapter: sqlite3
  database: db/test.sqlite3
  timeout: 5000

production:
  adapter: sqlite3
  database: db/production.sqlite3
  timeout: 5000

Im Bereich development wird die Datenbank für die Entwicklungsumgebung konfiguriert. Die anderen beiden Umgebungen test und production ignorieren wir zunächst. Dazu später mehr.

Einstellungen

Sie können hier die Einstellungen für den verwendeten Datenbankadapter, den Namen und Pfad zur Datenbankdatei und den Timeout vornehmen. Die bereits vorhandenen Werte sind Standardwerte, die Rails beim Generieren des Projekts angelegt hat. Diese können Sie übernehmen oder nach Ihren Wünschen anpassen. Auf den Eintrag des verwendeten Datenbankadapters haben Sie beim Generieren eines Rails-Projektes Einfluss, indem Sie den Parameter --database Adaptername oder -d Adaptername übergeben:

rails projektname --database mysql

Standard: SQLite3

Lassen Sie wie wir diesen Parameter weg, setzt Rails den Wert standardmäßig auf sqlite3.

In unserem Beispiel übernehmen wir die von Rails gesetzten Standardwerte. Die SQLite3-Datenbankdatei development.sqlite3 hat Rails bei der Anlage des Projekts im Verzeichnis db angelegt.

Sollten Sie einen anderen Datenbankadapter verwenden, müssen Sie die Datenbank noch mit dem folgenden Befehl anlegen:

rake db:create

Zum Speichern unserer Bookmarks benötigen wir eine Tabelle, die die Werte zu unseren Bookmarks, wie die URL, den Titel und evtl. einen Kommentar, speichert. Da Rails objektorientiert ist und wir deshalb nicht über die manuelle Eingabe von SQL-Befehlen auf Tabellen zugreifen können, benötigen wir auch eine Klasse, über deren Objekte der Zugriff auf die Tabelle möglich ist.

Mit Models werden in Rails Klassen bezeichnet, die einen Zugriff auf Datenbanktabellen erlauben. Rails enthält dazu das Framework ActiveRecord .

Model-Generator

Das heißt, als Nächstes müssen wir ein Model erstellen. Dazu stellt uns Rails den model -Generator zur Verfügung, der als Pflichtparameter den Namen des Models im Singular erwartet:

ruby script/generate model bookmark

Der Generator legt folgende Verzeichnisse und Dateien an:

exists  app/models/
exists  test/unit/
exists  test/fixtures/
create  app/models/bookmark.rb
create  test/unit/bookmark_test.rb
create  test/fixtures/bookmarks.yml
create  db/migrate
create  db/migrate/001_create_bookmarks.rb

Neben der Datei app/models/bookmark.rb für das Model hat der Generator auch eine Test-Datei test/unit/bookmark_test.rb, eine Datei test/fixtures/bookmarks.yml zum Anlegen von Testdaten (Fixtures), und eine Migration-Datei, db/migrate/001_create_bookmarks.rb, angelegt. Die Test-Datei und die Fixtures interessieren uns im Moment nicht. Wir wollen uns zunächst mit der Migration beschäftigen.


Rheinwerk Computing - Zum Seitenanfang

Migrations  Zur nächsten ÜberschriftZur vorigen Überschrift

Migration ist ein ganz wichtiges Konzept in Rails. Innerhalb einer Migration-Datei wird die Tabellenstruktur einer Datenbanktabelle in Ruby-Code beschrieben. Auch Änderungen an einer Tabelle, weil ein Feld nicht mehr benötigt wird oder neue Felder hinzukommen, werden über Migration durchgeführt. Das heißt, in der Migration-Datei wird alles definiert: wie die Tabelle heißt, die erzeugt werden soll, welche Felder diese Tabelle hat, und welchen Datentyp diese Felder haben. Und das wird nicht etwa in SQL-Befehlen definiert, sondern in Ruby-Code, der speziell innerhalb des Frameworks ActiveRecord für die Lösung dieses Problems entwickelt wurde. Deshalb spricht man bei Migrations auch von einer Domain Specific Language . Die Migration-Datei kann ausgeführt werden - wie das geht, zeigen wir Ihnen gleich - und dann wird der darin enthaltene Ruby-Code in SQL-Befehle übersetzt. Eine ausführliche Beschreibung des Migration-Konzepts erhalten Sie in Kapitel 10.

Per Konvention ist definiert, dass zu einem Model eine Tabelle gehört, die so heißt wie das Model im Plural.

Migration-Datei

Das alles steckt in dem Generator, den wir zur Erzeugung des Models benutzt haben. Das heißt, zu der Model-Datei legt er auch eine Migration-Datei im Verzeichnis db/migrate an, die schon den Befehl zum Anlegen der Tabelle enthält:

Listing  db/migrate/001_create_bookmarks.rb

class CreateBookmarks < ActiveRecord::Migration
  def self.up
    create_table :bookmarks do |t|

      t.timestamps
    end
  end

  def self.down
    drop_table :bookmarks
  end
end

Felder ergänzen

Das, was wir noch ergänzen müssen, sind die einzelnen Feldnamen und Feldtypen. Wir benötigen die Felder title, url und comment . Der Eintrag t.timestamps erzeugt die beiden Datumsfelder created_at und updated_at, in denen gespeichert wird, wann ein Datensatz angelegt wurde und wann ein Datensatz geändert wurde. Rails setzt und aktualisiert diese beiden Felder später automatisch. Sehr praktisch.

Die Datentypen in der Migration haben eigene Bezeichnungen. Zum Beispiel heißt ein Varchar(255) in der Migration string:

Listing  db/migrate/001_create_bookmarks.rb

class CreateBookmarks < ActiveRecord::Migration
  def self.up
    create_table :bookmarks do |t|
      t.string :title, :url
      t.text :comment
      t.timestamps
    end
  end

  def self.down
    drop_table :bookmarks
  end
end

Sexy Migrations
Hätten wir beim Generieren des Models auch die Feldnamen und die Feldtypen mit angegeben ( ruby script/generate model bookmark title:string url:string comment:text ), hätte der Generator die Migration-Datei inklusive der Feldnamen und -typen erstellt.

rake db:migrate

Die Migration-Datei müssen wir jetzt ausführen, sprich in SQL-Befehle umwandeln. Wenn Sie diesen Umwandlungsprozess verfolgen wollen, öffnen Sie bitte zwei Konsolen-Fenster und wechseln in beiden in Ihr Projektverzeichnis. In dem Fenster, in dem Sie den Prozess verfolgen möchten, starten Sie den lokalen Rails-Server über ruby script/server, und in dem anderen Fenster führen Sie die Migration-Datei über folgenden Befehl aus:

rake db:migrate

Der Befehl liefert folgende Ausgabe:

== 1 CreateBookmarks: migrating ===========================
-- create_table(:bookmarks)
   -> 0.0232s
== 1 CreateBookmarks: migrated (0.0233s) ==================

Das sagt nur aus, dass die Migration-Datei fehlerfrei ausgeführt wurde. Den interessanteren Teil, was wirklich in SQL passiert ist, können Sie sich jetzt in dem Fenster ansehen, in dem Sie den Server gestartet hatten:

CREATE TABLE bookmarks ("id" INTEGER PRIMARY KEY AUTOINCREMENT
NOT NULL, "title" varchar(255) DEFAULT NULL, "url"
varchar(255) DEFAULT NULL, "comment" text DEFAULT NULL,
"created_at" datetime DEFAULT NULL, "updated_at"
datetime DEFAULT NULL)

ID

Interessant ist, dass ein Feld id erstellt wurde, ohne dass wir dieses Feld in der Migration-Datei angegeben haben. Das Feld id wird immer automatisch als Primärschlüssel einer Tabelle miterstellt mit dem Attribut auto_increment, das heißt, jeder neue Datensatz erhält automatisch die nächsthöhere ID und ist deshalb nie leer.

Hätten wir nicht SQLite3, sondern zum Beispiel eine Oracle-Datenbank eingesetzt, wäre die Migration-Datei an Oracle angepasst übersetzt worden. Das heißt, die Migration-Datei ist immer gleich, egal welches Datenbanksystem verwendet wird.


Rheinwerk Computing - Zum Seitenanfang

ActiveRecord  Zur nächsten ÜberschriftZur vorigen Überschrift

Der Zugriff auf die nun erstellte Tabelle bookmarks erfolgt über Objekte des Models Bookmark . Das heißt, das Model selbst repräsentiert die Tabelle, und die Objekte repräsentieren einen Datensatz in der Tabelle.

Wenn Sie das Model bookmark.rb im Verzeichnis app/models öffnen, sehen Sie, dass die Klasse Bookmark von ActiveRecord::Base erbt und ansonsten leer ist:

Listing  app/models/bookmark.rb

class Bookmark < ActiveRecord::Base
end

Das lassen wir auch erst einmal so, weil die Klasse alle Funktionalitäten, die zum Zugriff auf die Tabelle nötig sind, von ActiveRecord geerbt hat. Wie genau ActiveRecord funktioniert, erfahren Sie in Kapitel 10.


Rheinwerk Computing - Zum Seitenanfang

Datenbankzugriff in der Konsole testen  topZur vorigen Überschrift

ruby script/console

Sie können den Zugriff auf die Tabelle über den Aufruf der Rails-Konsole (ruby script/console) innerhalb der Rails-Umgebung testen. Die Rails-Konsole erlaubt es Ihnen, die Befehle interaktiv auszuprobieren. In dieser Konsole stehen Ihnen alle Klassen Ihres Projekts zur Verfügung. Das heißt, Sie können zum Beispiel alle bisher angelegten Bookmark-Datensätze zählen:

ruby script/console
Loading development environment (Rails 2.0.2)
>> Bookmark.count
=> 0

Magie von ActiveRecord

Um einen neuen Eintrag in der Tabelle bookmarks vorzunehmen, erzeugen Sie ein neues Objekt der Klasse Bookmark und weisen diesem Objekt die einzelnen Feldwerte über Attribute zu. Das ist die Magie, die ActiveRecord uns zur Verfügung stellt. ActiveRecord erzeugt nämlich Methoden, die so heißen wie die einzelnen Felder der Tabelle, um die Feldwerte auszulesen. Um einen Wert zu setzen, erhält die Methode ein Gleichheitszeichen am Ende. Und da die Klasse Bookmark von ActiveRecord erbt, steht diese Funktionalität auch in der Klasse Bookmark zur Verfügung:

>> bookmark = Bookmark.new
=> #<Bookmark id: nil, title: nil, url: nil, ...
>> bookmark.title = "Ruby on Rails"
=> "Ruby on Rails"
>> bookmark.url = "http://www.rubyonrails.com"
=> "http://www.rubyonrails.com"

Speichern können Sie den neuen Eintrag über den Aufruf von:

>> bookmark.save

Wenn Sie den lokalen Rails-Server noch gestartet hatten, konnten Sie nach dem Aufruf des save -Befehls Folgendes beobachten:

INSERT INTO bookmarks ("updated_at", "title", "url",
"comment", "created_at") VALUES('2007-12-20 21:12:15',
'Ruby on Rails', 'http://www.rubyonrails.com', NULL,
'2007-12-20 21:12:15')

Das heißt, es ist wirklich ein Datensatz hinzugefügt worden:

>> Bookmark.count
=> 1

create

Eine kürzere Möglichkeit, einen neuen Datensatz anzulegen, ist die Anwendung der Methode create, der Sie die einzelnen Werte als Hash übergeben:

>> Bookmark.create(:title => "Ruby",
:url => "http://www.ruby-lang.org")
=> #<Bookmark id: 2, title: "Ruby",
url: "http://www.ruby-lang.org",
created_at: "2007-12-01 18:56:45",
...
>> Bookmark.count
=> 2

find

Über die Methode find können Sie auf die einzelnen Datensätze zugreifen. Dazu übergeben Sie der Methode die ID des gesuchten Datensatzes als Parameter:

>> b = Bookmark.find(1)
=> #<Bookmark id: 1, title: "Ruby on Rails",
url: "http://www.rubyonrails.com",
created_at: "2007-12-01 18:52:02",
...

Auf die einzelnen Werte greifen Sie durch Aufruf der Methoden für die Feldnamen zu:

>> b.title
=> "Ruby on Rails"
>> b.url
=> "http://www.rubyonrails.com"
Ausgabe eines Objektes
Wenn Sie alle Werte eines Objektes ausgeben möchten, können Sie den y -Befehl in der Rails-Konsole verwenden:
>> y Bookmark.find(1)
--- !ruby/object:Bookmark
attributes:
updated_at: 2007-12-04 22:47:13
title: Ruby on Rails
url: http://www.rubyonrails.com

find(:all)

Um alle angelegten Bookmarks auszulesen, übergeben Sie der Methode find den Parameter :all . Das Ergebnis ist ein Array:

>> Bookmark.find(:all)
=> [#<Bookmark id: 1, title: "Ruby on Rails",
url: "http://www.rubyonrails.com",
created_at: "2007-12-01 18:52:02",
...,
#<Bookmark id: 2, title: "Ruby",
url: "http://www.ruby-lang.org",
created_at: "2007-12-01 18:56:45"
...]

Wenn Sie zum Beispiel nur den Titel aller vorhandenen Bookmarks ausgeben möchten, können Sie das lösen, indem Sie mit einer each -Schleife über das Ergebnisarray von find(:all) iterieren und immer nur den Titel jedes Elementes ausgeben:

>> Bookmark.find(:all).each do |bookmark|
?>   puts bookmark.title
>> end
Ruby on Rails
Ruby

Oder Sie erzeugen ein Array, das nur die Titel der einzelnen Datensätze enthält:

>> Bookmark.find(:all).collect(&:title)
=> ["Ruby on Rails", "Ruby"]

Aber zunächst noch weitere Informationen zum Umgang mit ActiveRecord-Klassen. Zur Zeit ist es möglich, einen leeren Datensatz anzulegen, indem wir die Methode create aufrufen, ohne ihr Werte zu übergeben:

>> Bookmark.create
=> #<Bookmark id: 3, title: nil, url: nil, ...
>> Bookmark.count
=> 3

Pflichtfelder definieren

Da wir nicht wollen, dass leere Datensätze angelegt werden, können wir im Model angeben, welche Felder Pflichtfelder sind. Das heißt, wenn diese Felder dann nicht gesetzt sind, wird der Datensatz nicht gespeichert. In unserem Beispiel soll der Datensatz nur gespeichert werden, wenn die Felder title und url gesetzt sind:

Listing  app/models/bookmark.rb

class Bookmark < ActiveRecord::Base
  validates_presence_of :title
  validates_presence_of :url
end

reload!

Da wir eine Änderung am Model vorgenommen haben, müssen wir, bevor wir testen, ob die Änderungen umgesetzt werden, die Applikation neu starten, da die Konsole beim Start die Entwicklungsumgebung lädt und unsere Änderung nach dem Laden erfolgt ist. Die Applikation wird über den Befehl reload! neu gestartet:

>> reload!
Reloading...
=> true

Jetzt ist es nicht mehr möglich, einen leeren Datensatz zu speichern. Das können wir leicht kontrollieren, indem wir zuerst die aktuelle Anzahl der bereits angelegten Datensätze mit dem Befehl Bookmark.count abfragen, anschließend versuchen, einen leeren Datensatz über den Befehl Bookmark.create anzulegen, und dann noch einmal die Anzahl der angelegten Datensätze kontrollieren:

>> Bookmark.count
=> 3
>> Bookmark.create
=> #<Bookmark id: nil, title: nil, url: nil,
created_at: nil,
...
>> Bookmark.count
=> 3

Wenn dagegen die beiden Pflichtfelder gesetzt sind, wird ein neuer Datensatz angelegt:

>> Bookmark.count
=> 3
>> Bookmark.create(:title => "css Zen Garden",
:url => "http://www.csszengarden.com")
=> #<Bookmark id: 4, title: "css Zen Garden",
url: "http://www.csszengarden.com",
created_at: "2007-12-01 19:21:58"
...
>> Bookmark.count
=> 4

destroy

Wenn wir uns jetzt wieder die Titel aller bisher angelegten Bookmarks ausgeben lassen, befindet sich der leere Datensatz mitten in dem Array. Sie können diesen Datensatz mit Hilfe der Methode find_by_title, der Sie den Wert nil übergeben, suchen und mit der Methode destroy löschen:

>> Bookmark.find(:all).collect(&:title)
=> ["Ruby on Rails", "Ruby", nil, "css Zen Garden"]

>>
Bookmark.find_by_title(nil).destroy
...
>> Bookmark.find(:all).collect(&:title)
=> ["Ruby on Rails", "Ruby", "css Zen Garden"]

Wir haben jetzt in der ruby script/console so mit dem Model gearbeitet, wie wir das später im Controller tun werden. Dazu aber im nächsten Abschnitt mehr.



Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

 <<   zurück
  Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Ruby on Rails 2
Ruby on Rails 2
Jetzt Buch bestellen
 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchtipps
Zum Rheinwerk-Shop: Ruby on Rails 3.1






 Ruby on Rails 3.1


Zum Rheinwerk-Shop: Responsive Webdesign






 Responsive Webdesign


Zum Rheinwerk-Shop: Suchmaschinen-Optimierung






 Suchmaschinen-
 Optimierung


Zum Rheinwerk-Shop: JavaScript






 JavaScript


Zum Rheinwerk-Shop: Schrödinger lernt HTML5, CSS3 und JavaScript






 Schrödinger lernt
 HTML5, CSS3
 und JavaScript


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2008
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern