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.5 CRUD - Create - Read - Update - Delete  topZur vorigen Überschrift

Grundoperationen

Im letzten Abschnitt haben wir ein ActiveRecord-Model für den objektorientierten Zugriff auf unsere Datenbanktabelle bookmarks erstellt. Mit einem Objekt dieses Models können wir die vier Grundoperationen durchführen:

  1. Create
    einen neuen Datensatz erstellen
  2. Read
    einen Datensatz lesen
  3. Update
    einen vorhandenen Datensatz ändern
  4. Delete
    einen Datensatz löschen

Bis jetzt haben wir all das nur in der ruby script/console eingesetzt. Wir möchten das jetzt auch in unserer Bookmarkverwaltung nutzen.

Zunächst sollen unsere Bookmarks, die wir bis jetzt im Controller manuell in einem Array gesetzt haben, aus der Datenbank gelesen werden. In den darauffolgenden Schritten wollen wir dann in der Lage sein, einen neuen Bookmark hinzuzufügen, einen vorhandenen zu ändern oder zu löschen. Dazu müssen wir die entsprechenden Funktionalitäten des Models sowohl im Controller als auch in den Views einsetzen.

Beginnen wir mit unserem Bookmarks-Controller:

Listing  app/controllers/bookmarks_controller.rb

class BookmarksController < ApplicationController
  def index
    @bookmarks = ["http://www.rubyonrails.com",
		  "http://www.ruby-lang.org"]
  end

  def edit
  end

  def new
  end
end

Die index-Action

Als Erstes ersetzen wir das Array, das wir manuell mit zwei Bookmarks gesetzt haben, durch einen Model-Aufruf, um die vorhandenen Bookmarks aus der Datenbank auszulesen:

def index
  @bookmarks = Bookmark.find(:all)
end

Objektattribute ausgeben

Diese Änderung bedingt, dass auch im View index.html.erb Änderungen vorgenommen werden müssen. Vorher haben wir einfach nur jedes einzelne Element des Arrays in dem View ausgegeben. Das Array @bookmarks enthält aber jetzt Objekte vom Typ Bookmark, das heißt, im View können die einzelnen Attribute der Objekte angezeigt werden. Wir entscheiden uns zunächst dafür, für jeden Bookmark die URL auszugeben:

Listing  app/views/bookmarks/index.html.erb

<% @title = "liste" %>
<h2>Liste der Favoriten</h2>

<ul>
<% @bookmarks.each do |bookmark|%>
  <li><%= h bookmark.url %></li>
<% end %>
</ul>

Schöner wäre es, wenn wir nicht nur die URL zu jedem Bookmark ausgeben würden, sondern wenn die URL auch anklickbar wäre. Dazu müssen wir die Ausgabe der URL aus unserem letzten Listing wie folgt anpassen:

<li>
  <a href = «%= h bookmark.url %>»<%= h bookmark.title%>
</li>

link_to

Da der eingebettete Ruby-Code innerhalb des HTML-Codes nicht so gut aussieht und auch etwas umständlich zu tippen ist, stellt Rails uns ActionView-Helper zur Verfügung. ActionView-Helper sind Hilfsmethoden, mit denen wir HTML-Code generieren können. Den Link hätten wir auch mit dem Einsatz des ActionView-Helpers link_to realisieren können:

<li><%= link_to h(bookmark.title), h(bookmark.url) %></li>

Unsere neue Index-Seite können wir im Browser testen:

Abbildung  Verlinkte Titel - index.html.erb

show

Neben der Anzeige des Titels unserer Bookmarks und der Verlinkung mit der jeweiligen URL könnten wir auch noch das Kommentarfeld und das Erstellungs- und Änderungsdatum unserer Bookmarks anzeigen. Da dafür auf der Index-Seite zu wenig Platz ist oder weil wir das auch einfach nicht auf der Index-Seite anzeigen möchten, erstellen wir für diese Zusatzinformationen eine Detailseite. Diese Detailseite wird üblicherweise show genannt. Das heißt, wir müssen im Bookmarks-Controller eine neue Action show hinzufügen, und zur Ausgabe müssen wir einen neuen View, show.html.erb, anlegen. Beginnen wollen wir mit dem Controller.

Die show-Action

Datensatz laden

Die Action show soll einen bestimmten Datensatz laden, der dann im View angezeigt werden soll. Es soll also ein konkretes Modelobjekt bzw. ein Datensatz geladen werden. Das können wir mit der Methode find realisieren, der wir die ID des Datensatzes, den wir anzeigen möchten, übergeben:

Bookmark.find(2)

Die Action show kennt die ID des Datensatzes aber nicht, weil diese über die URL übergeben wird:

http://localhost:3000/controller/action/id

Der Aufbau der URL wird durch eine Konvention in Rails bestimmt, über die Sie in Kapitel kap_actioncontroller ab Seite kap_actioncontroller mehr erfahren. Für uns ist jetzt nur wichtig, dass das so ist und dass wir den Parameter ID aus der URL auslesen müssen:

Bookmark.find(params[:id]

Daraus folgt unsere Action show:

Listing  app/controllers/bookmarks_controller.rb

def show
  @bookmark = Bookmark.find(params[:id])
end

@bookmark

In der Instanzvariablen @bookmark steht dem View show.html.erb dann der Datensatz zur Verfügung, dessen ID über die URL an die Action show übergeben wurde.

Als Nächstes erstellen wir also im Verzeichnis app/views/bookmarks eine neue Datei show.html.erb, in der wir den Titel, die URL, den Kommentar, das Erstellungs- und das Änderungsdatum eines Bookmarks ausgeben:

Listing  app/views/bookmarks/show.html.erb

<h2>Detail zum Favorit</h2>

<p>Titel: <%= h @bookmark.title %></p>

<p>URL: <%= h @bookmark.url %></p>

<p>Kommentar: <%= h @bookmark.comment %></p>

<p>Erstellt am: <%= @bookmark.created_at %></p>

<p>Geändert am: <%= @bookmark.updated_at %></p>

Testen können Sie das durch Aufruf der URL:

http://localhost:3000/bookmarks/show/2

Abbildung  http://localhost:3000/bookmarks/show/2

strftime

Um das Erstellungs- und Änderungsdatum im deutschen Datumsformat mit Angabe der Uhrzeit zu formatieren, können wir die Methode strftime nutzen:

<p>
Erstellt am:
<%= @bookmark.created_at.strftime("%d.%m.%Y %H:%M") %>
</p>

<p>
Geändert am:
<%= @bookmark.updated_at.strftime("%d.%m.%Y %H:%M") %>
</p>

Abbildung  http://localhost:3000/bookmarks/show/2

Was uns jetzt noch fehlt, ist ein Link von der Index-Seite auf die Detailseiten der einzelnen Bookmarks und von der Detailseite ein Link zurück zur Index-Seite. Dazu müssen wir in den Views index.html.erb und show.html.erb einen Link hinzufügen:

Listing  app/views/bookmarks/index.html.erb

<% @title = "liste" %>
<h2>Liste der Favoriten</h2>

<ul>
<% @bookmarks.each do |bookmark|%>
  <li>
    <%= link_to h(bookmark.title), h(bookmark.url) %>
    (<%= link_to "Details", :action => "show",
    :id => bookmark.id %>)
  </li>
<% end %>
</ul>

Listing  app/views/bookmarks/show.html.erb

...
<p><%= link_to "Zurück zur Liste", :action => "index" %></p>

Abbildung  http://localhost:3000/bookmarks

Formular zur Erstellung eines neuen Datensatzes

new

Jetzt erstellen wir ein Formular, um neue Bookmarks hinzufügen zu können. Dazu steht uns im Controller die Action new zur Verfügung. In dieser Action wird ein neues, leeres Bookmark-Objekt erstellt, das wir im View über das Formular mit Werten füllen können:

def new
@bookmark = Bookmark.new
end

form_for

In dem View app/views/bookmarks/new.html.erb werden wir das Formular zum Anlegen eines neuen Bookmarks hinterlegen. Auch zur Formularentwicklung stellt Rails einen ActionView-Helper zur Verfügung: form_for . Bei form_for handelt es sich um einen Block, dem Sie übergeben, auf welches Objekt sich die Felder des Formulars beziehen, in unserem Fall ist das das Bookmark-Objekt, das beim Aufruf des Formulars in der Action new erzeugt wurde, und an welche Action die Formularwerte geschickt werden, in unserem Fall ist das die Action create, die wir nach der Erstellung des Formulars noch im Controller entwickeln müssen:

Listing  app/views/bookmarks/new.html.erb

<% form_for :bookmark, :url => {:action => "create"} do |f| %>
<% end %>

Formular Helper

In dem Formular fehlen jetzt noch die einzelnen Felder. Hier legen Sie alle die Felder an, die in der Datenbanktabelle bookmarks gesetzt werden können. Das heißt, alle außer id, created_at und updated_at, weil diese automatisch von Rails gesetzt werden. Wichtig ist, dass die Felder genauso heißen wie in der Datenbanktabelle. Auch für die Erzeugung der einzelnen Formularelemente stehen Helper zur Verfügung: text_field, text_area und submit_tag . Unterhalb des Formulars fügen wir noch einen Link zurück zur Index-Seite ein:

<% @title = "neu" %>
<h2>Neuen Favorit erstellen</h2>
<% form_for :bookmark, :url => {:action => "create"} do |f| %>
<p>
  <label for="bookmark_title">Titel</label>
  <%= f.text_field :title %>
</p>
<p>
  <label for="bookmark_url">URL</label>
  <%= f.text_field :url %>
</p>
<p>
  <label for="bookmark_comment">Kommentar</label>
  <%= f.text_area :comment %>
</p>
<p>
  <%= submit_tag "speichern" %>
</p>
<% end %>
<p><%= link_to "Zurück zur Liste", :action => "index" %></p>

Formular aufrufen

Über die URL http://localhost:3000/bookmarks/new können Sie das Formular im Browser aufrufen:

Abbildung  http://localhost:3000/bookmarks/new

Abschicken können Sie es noch nicht, weil wir im Controller die Action create noch nicht definiert haben.

create

Die Action create soll aus den Formularwerten ein neues Bookmark-Objekt erzeugen und speichern, um in der Datenbank einen neuen Datensatz zu erzeugen. Da die Formularfelder genauso heißen wie in der Datenbank, können wir sie als Hash übergeben. In Rails liest man die Parameter eines Formulars über params[:Formularname] . Daraus folgt für unsere Action create:

def create
  @bookmark = Bookmark.new(params[:bookmark])
end

save

Das Objekt @bookmark muss dann noch gespeichert werden. Da die Methode save entweder true oder false zurückliefert, können wir das auch abfragen und entsprechend reagieren. Wenn das Speichern erfolgreich war, soll zur Index-Seite weitergeleitet werden. Wenn der Datensatz nicht gespeichert werden kann, zum Beispiel weil nicht alle Pflichtfelder gesetzt sind, soll wieder der View new.html.erb angezeigt werden, aber die Formularfelder, die ausgefüllt waren, sollen erhalten bleiben. Das heißt, in diesem Fall erfolgt keine Weiterleitung, sondern es wird wieder das Formular, also der View new.html.erb, angezeigt, ohne die Seite neu zu laden:

def create
  @bookmark = Bookmark.new(params[:bookmark])
  if @bookmark.save
    redirect_to :action => "index"
  else
    render :action => "new"
  end
end

Das können Sie jetzt testen, indem Sie einmal ein vollständig ausgefülltes Formular abschicken und einmal nur den Titel ausfüllen und dann das Formular abschicken.

Formular zum Ändern eines Datensatzes

edit

Das Ändern eines vorhandenen Bookmarks ist relativ einfach. Dazu nutzen wir die Action edit im Controller. edit ist ähnlich wie new . Der Unterschied besteht darin, dass edit einen vorhandenen Bookmark lädt, dessen ID wie bei der Action show über die URL übergeben wird:

def edit
  @bookmark = Bookmark.find(params[:id])
end

Das Formular für den View edit.html.erb übernehmen wir von dem View new.html.erb . Wir werden später zeigen, wie man diese Duplizierung vermeiden kann. Das Formular zum Ändern eines Bookmarks senden wir aber nicht an die Action create, sondern an die Action update, die wir noch erstellen müssen, und wir übergeben die ID des Bookmarks, der editiert werden soll, an die Action update:

Listing  app/views/bookmarks/edit.html.erb

<% @title = "bearbeiten" %>
<h2>Favorit bearbeiten</h2>

<% form_for :bookmark, :url => {:action => "update",
:id => @bookmark.id} do |f| %>

<p>
  <label for="bookmark_title">Titel</label>
  <%= f.text_field :title %>
</p>
<p>
  <label for="bookmark_url">URL</label>
  <%= f.text_field :url %>
</p>
<p>
  <label for="bookmark_comment">Kommentar</label>
  <%= f.text_area :comment %>
</p>
<p>
  <%= submit_tag "speichern" %>
</p>

<% end %>

<p><%= link_to "Zurück zur Liste", :action => "index" %></p>

update

Damit wir das testen können, müssen wir noch im Controller die Action update entwickeln. Die Action update lädt über die übergebene ID den zu editierenden Bookmark, und dann ändert sie alle Werte, die über das Formular übergeben werden über die Methode update_attributes . Da diese Methode true oder false zurückliefert, können wir darauf abfragen und entsprechend reagieren. Wenn der Datensatz erfolgreich upgedatet werden konnte, soll zur Index-Seite weitergeleitet werden. Wenn nicht, soll das Formular zum Ändern geladen werden:

def update
  @bookmark = Bookmark.find(params[:id])
  if @bookmark.update_attributes(params[:bookmark])
    redirect_to :action => "index"
  else
    render :action => "edit"
  end
end

Testen können Sie das über den Aufruf der URL:

http://localhost:3000/bookmarks/edit/1

Abbildung  http://localhost:3000/bookmarks/edit/1

Links anlegen

Was uns noch fehlt, sind Links von der Index-Seite aus, um neue Bookmarks anzulegen, vorhandene zu editieren oder auch zu löschen (wenn wir auch das Löschen noch nicht programmiert haben), damit wir die jeweiligen URLs nicht immer händisch im Browser eingeben müssen. Dazu müssen die entsprechenden Links in der index.html.erb hinzugefügt werden:

Listing  app/views/bookmarks/index.html.erb

<% @title = "liste" %>
<h2>Liste der Favoriten</h2>

<ul>
  <% @bookmarks.each do |bookmark|%>
  <li>
    <%= link_to h(bookmark.title), h(bookmark.url) %>
    (<%= link_to "Details", :action => "show",
    :id => bookmark.id %> |
    <%= link_to "ändern", :action => "edit",
    :id => bookmark.id %> |
    <%= link_to "löschen", :action => "destroy",
    :id => bookmark.id %>
    )
  </li>
<% end %>
</ul>

<p>
  <%= link_to "Neuen Favorit erstellen", :action => "new" %>
</p>

Abbildung  Die Linksammlung

:confirm

Um ein versehentliches Löschen eines Bookmarks zu verhindern, ist es sinnvoll, eine JavaScript-Abfrage vorzuschalten. Dazu müssen wir im link_to -Helper in der index.html.erb noch eine weitere Option hinzufügen:

<%= link_to "löschen", {:action => "destroy",
:id => bookmark.id},
:confirm => "Wollen Sie diesen Datensatz wirklich löschen?" %>

Löschen von Datensätzen

destroy

Jetzt müssen wir nur noch die Action destroy im Controller implementieren. Zuerst muss über den übergebenen Parameter id ein konkreter Bookmark geladen werden, der dann gelöscht wird. Unsere Action destroy soll keinen eigenen View erhalten, weil das wenig sinnvoll ist. Nach dem Löschen soll eine Weiterleitung zur Index-Seite erfolgen:

def destroy
  @bookmark = Bookmark.find(params[:id])
  @bookmark.destroy
  redirect_to :action => "index"
end

Testen können Sie das über den bereits angelegten Link zum Löschen auf der Index-Seite.

Am Beispiel der Bookmarkverwaltung haben Sie bis jetzt die Grundoperationen kennengelernt, um Objekte anzulegen, zu lesen, zu ändern und zu löschen. Wir haben im Controller die entsprechenden Actions angelegt und die erforderlichen Views erstellt.

Resource- und Scaffold-Generatoren

Da das eine Anforderung ist, die immer wieder vorkommt, gibt es in Rails Generatoren, die automatisch die Controller mit den erforderlichen Actions anlegen und die dazugehörigen Views erstellen. Wir haben es in diesem Beispiel manuell gemacht, um zu zeigen, wie das im Einzelnen funktioniert und was letztendlich hinter den Generatoren steckt, wenn wir diese in den nächsten Beispielen einsetzen.

Über den Generator

ruby script/generate resource Modelname Feldname:Feldtyp Feldname:Feldtyp ...

werden das Model, die Migration-Datei und der Controller angelegt.

Über den Generator

ruby script/generate scaffold Modelname Feldname:Feldtyp Feldname:Feldtyp ...

werden das Model, die Migration-Datei, der Controller mit den erforderlichen sieben Actions für CRUD und die dazugehörigen Views angelegt.



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