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 9 Steuerzentrale mit ActionController
  Pfeil 9.1 Grundlagen
  Pfeil 9.2 Aufgaben des Controllers
  Pfeil 9.3 Filter
  Pfeil 9.4 Routing


Rheinwerk Computing - Zum Seitenanfang

9.2 Aufgaben des Controllers  Zur nächsten ÜberschriftZur vorigen Überschrift

Die Klasse ActionController stellt zur Bewältigung der Aufgaben eines Controllers eine Reihe von Methoden zur Verfügung. Die wichtigsten dieser Methoden werden wir Ihnen in den folgenden Abschnitten zeigen.


Rheinwerk Computing - Zum Seitenanfang

Daten aus HTTP-Anfragen empfangen  Zur nächsten ÜberschriftZur vorigen Überschrift

params

Auf Daten, die über die HTTP-Methoden GET, POST, PUT und DELETE gesendet werden, kann im Controller über die Methode params[] zugegriffen werden:

# Aufruf einer URL mit GET-Methode
http://localhost:3000/countries?page=3&num=10

# Auslesen des Parameters :page im Controller
params[:page]
=> 3

# Auslesen des Parameters :num im Controller
params[:num]
=> 10
params ist kein Hash
Der Zugriff auf die Methode params erfolgt wie der Zugriff auf einen Hash, was auch beabsichtigt ist, aber genau genommen ist [] eine Methode des Objekts params. Im folgenden Beispiel wird eine Klasse mit der Methode, die den Namen [] trägt, definiert:
class Frage
    def [](var)
      if var=="wie gehts"
        return "gut, danke"
      else
        return "wie bitte?"
      end
    end
  end

  frage = Frage.new
  puts frage["wie gehts"]
  # => gut, danke
Dieses Verhalten wird auch als »hashlike« bezeichnet. Was bedeutet, dass zwar der Zugriff wie bei einem Hash erfolgt, aber nicht die Methoden eines Hash-Objektes zur Verfügung stehen. Das gleiche gilt u.a. auch für session und cookies.

request

Mit Hilfe der Methode request haben Sie Zugriff auf alle Informationen, die Rails über die aktuelle Anfrage vorliegen. Dazu zählen unter anderem:

  • request.remote_ip
    Gibt die IP-Adresse des Clients zurück.
  • request.method
    Gibt die Art der Anfrage ( :get , :post , :put oder :delete ) zurück.
  • request.get?
    Liefert true zurück, wenn die Anfrage mit der HTTP-Methode GET gesendet wurde.
  • request.post?
    Liefert true zurück, wenn die Anfrage mit der HTTP-Methode POST gesendet wurde.
  • request.put?
    Liefert true zurück, wenn die Anfrage mit der HTTP-Methode PUT gesendet wurde.
  • request.delete?
    Liefert true zurück, wenn die Anfrage mit der HTTP-Methode DELETE gesendet wurde.
  • request.xml_http_request?
    Liefert true zurück, wenn es sich um eine Ajax-Anfrage handelt. Als Abkürzung kann auch request.xhr? verwendet werden.
  • request.domain
    Gibt die angefragte Domain zurück.
  • request.env
    Mit der Methode request.env ist es möglich, auf die Umgebungsvariablen, die u. a. vom Apache-Webserver gesetzt werden, zuzugreifen. Zum Beispiel request.env["HTTP_USER_AGENT"] , um den anfragenden Browser abzufragen, oder request.env["HTTP_ACCEPT_LANGUAGE"] , um die im anfragenden Browser eingestellte Sprache abzufragen.
  • request.ssl?
    Liefert true zurück, wenn es sich um eine SSL-Abfrage handelt.

Rheinwerk Computing - Zum Seitenanfang

Datenbankabfragen über Model-Klassen  Zur nächsten ÜberschriftZur vorigen Überschrift

Delegation an das Model

Wichtig ist, dass der Controller möglichst viel an das Model delegiert. Anstatt selbst eine Datenbankabfrage wie diese

@airports = Country.find(:first,
			 :conditions=>{:code=>'DE'}).airports

zu machen, sollte im Model eine Methode definiert werden, die diese Anfrage ausführt und die vom Controller aufgerufen wird.

@airports = Country.german_airports

Ein solcher Methodenaufruf lässt sich viel einfacher testen als eine Datenbankabfrage (siehe Kapitel »Test-Driven Development«) und erleichtert die Entwicklung dadurch ungemein.

Actions kurz halten

Allgemein sollten Sie daher darauf achten, dass Ihre Action nicht zu lang wird. Eine Action sollte in der Regel nicht mehr als 10 Zeilen enthalten.


Rheinwerk Computing - Zum Seitenanfang

Setzen und Abfragen von Cookies  Zur nächsten ÜberschriftZur vorigen Überschrift

Um ein Cookie zu setzen oder abzufragen, können Sie die Methode cookies nutzen. Zum Setzen eines Cookies erwartet die Methode den Namen des Cookies und die einzelnen Werte in Form eines Hashs als Parameter:

cookies[:user_id] = {
    :value => '8',
    :expires => 2.hours.from_now}

Sie können folgende Optionen beim Setzen eines Cookies angeben:

  • value:
    Wert des Cookies oder eine Liste von Werten (als Array)
  • path:
    Pfad, für den das Cookie gültig ist. Standardmäßig ist das Root-Verzeichnis der Applikation eingestellt.
  • domain:
    Domain, für die das Cookie gültig ist
  • expires:
    Zeitpunkt (als Time-Objekt), zu dem das Cookie abläuft, wie z. B. 30.minutes.from_now .
  • secure:
    Gibt an, ob es sich um ein sicheres Cookie handelt oder nicht. Der Standardwert ist false . Sichere Cookies können nur zu HTTPS-Servern übertragen werden.
  • http_only:
    Gibt an, ob das Cookie über Scripting zugänglich ist oder nur über HTTP. Standardmäßig ist false eingestellt.

Kurzschreibweise

Wenn Sie nur den value setzen möchten, können Sie auch die Kurzschreibweise nutzen:

cookies[:user_id] = '8'

Abfragen können Sie ein Cookie einfach, indem Sie der Methode cookies den Namen des Cookies übergeben:

cookies[user_id]
# => 8

Cookie löschen

Mit folgendem Aufruf können Sie ein Cookie löschen:

cookies.delete :user_id

Rheinwerk Computing - Zum Seitenanfang

Setzen und Abfragen von Sessions  Zur nächsten ÜberschriftZur vorigen Überschrift

Mit Hilfe von Sessions können Sie Objekte zwischen den einzelnen Anfragen zwischenspeichern. Das Speichern und Abfragen eines Objekts in einer Session ist ähnlich unkompliziert wie das Setzen und Abfragen eines Cookies.

Mit Hilfe der Methode session können Sie ein Objekt in einer Session speichern:

session[:user_id] = user.id

und ein Objekt aus einer Session abfragen:

@user = User.find(session[:user_id])

Die Methode session ist kein Hash, verhält sich aber wie params und cookies »hashlike«.

Session löschen

Mit folgendem Aufruf können Sie einen einzelnen Wert aus einer Session löschen:

session[:user_id] = nil

Eine komplette Session können Sie mit reset_session löschen.

Falls für einen Controller keine Sessions erforderlich sind, kann mit folgendem Befehl das Session-Management aus Gründen der Performancesteigerung deaktiviert werde:

class InfoController < ApplicationController
  session :off
end

Rheinwerk Computing - Zum Seitenanfang

Templates aufrufen  Zur nächsten ÜberschriftZur vorigen Überschrift

Instanzvariablen

In den Actions im Controller werden die dynamischen Inhalte, die in den Templates angezeigt werden sollen, ermittelt und in Instanzvariablen (Variablen mit führendem @-Zeichen) gespeichert, auf die die Templates zugreifen können, sie also als Templatevariablen nutzen.

template_root

Die Methode render, über die der Controller ein Template lädt, erwartet die Templates in dem Verzeichnis, das über die globale Variable template_root angegeben wurde. Standardmäßig ist das das Verzeichnis app/views . In einem Unterverzeichnis, das so heißt wie der Controller, werden die einzelnen Templates abgelegt. Die Templates sind nach den Actions innerhalb des Controllers benannt, von denen sie aufgerufen werden.

render

Durch Aufruf der Methode render wird das Template im Verzeichnis app/views/name_des_controllers aufgerufen, das so heißt wie die Action, aus der heraus die Methode aufgerufen wurde.

In dem folgenden Beispiel wird die Template-Datei new.html.erb aus dem Verzeichnis app/views/flights verwendet.

class FlightsController < ActionController
  ...
  def new
    @flight = Flight.new
    render
  end
  ...
end

Template auto- matisch laden

Zu diesem Zweck werden Sie die Methode render in der Praxis nicht nutzen, weil Rails automatisch am Ende einer Action das zugehörige Template lädt, wenn nichts anderes angegeben wurde. Das heißt, Sie können für diesen Fall auf den Aufruf der Methode render verzichten.

def new
  @flight = Flight.new
end

Sie können der Methode render auch den Namen des Templates, das geladen werden soll, übergeben. In dem folgenden Beispiel wird die Template-Datei new.html.erb verwendet.

def new
  @flight = Flight.new
  render :new
end

Namen übergeben

Oder Sie übergeben den Namen des Controllers und den Namen des Templates:

...
render :template => "flights/new"
...

Sie können auch den absoluten Pfad zum Template angeben:

...
render :file => "/absoluter-pfad/flights/new.html.erb"
...

Statt ein Template aufzurufen, können Sie der Methode render auch einen Text übergeben, der an der Oberfläche ausgegeben werden soll:

...
render :text => "hello world!"
...

Option :layout

Mit der Option :layout können Sie angeben, ob eine Layout-Datei geladen werden soll und wenn ja, welche.

Standardlayout deaktivieren

Um das Standardlayout für das zu ladende Template zu deaktivieren, übergeben Sie false:

...
render :new, :layout => false
...

Anderes Layout verwenden

Wenn Sie ein anderes als das Standardlayout für ein Template laden wollen, geben Sie den Namen der Layoutdatei aus dem Verzeichnis app/views/layouts an:

...
render :new, :layout => "name_des_layouts"
...

Mehr zu Layout-Dateien erfahren Sie im Abschnitt »Layouts« in Kapitel »Templatesystem mit ActionView«.

Unterschiedliche Darstellungsformate

respond_to

Rails bietet uns eine sehr einfache Methode an, respond_to, die wir im Controller einsetzen können, um die Ausgabe im Template in unterschiedlichen Formaten zu realisieren:

def show
  @flight = Flight.find(params[:id])
  respond_to do |format|
    format.html # show.html.erb
    format.xml { render :xml => @flight.to_xml }
  end
end

to_xml

Da das HTML-Format der Standardausgabe entspricht und es auch Standard ist, dass das passende Template zur Action im Controller geladen wird, müssen wir für den Fall, dass die Ausgabe in HTML erfolgen soll, nichts angeben. Im Fall der Ausgabe im XML-Format stellt uns ActiveRecord eine interessante Methode zur Verfügung, to_xml, mit der wir jedes ActiveRecord-Objekt in XML umwandeln können. Über render :xml erfolgt die Ausgabe im XML-Format.


Rheinwerk Computing - Zum Seitenanfang

Setzen von Flash-Nachrichten  Zur nächsten ÜberschriftZur vorigen Überschrift

Statusmeldungen

Um dem Benutzer kurze Statusmeldungen, wie z. B. »Sie wurden abgemeldet« oder »Datensatz wurde erfolgreich gelöscht«, anzuzeigen, können sogenannte Flash-Nachrichten verwendet werden, die vom Controller gesteuert werden. Eine Flash-Nachricht ist ein Hash, der nur für eine Anfrage gültig ist und danach wieder gelöscht wird. Dies hat also nichts mit dem Adobe-Flash-Format zu tun.

Abbildung  Beispiel einer Flash-Nachricht

:notice und :error

Bestätigungsmeldungen oder Notizen werden über die Flash-Nachricht flash[:notice] = "Text" an der Oberfläche ausgegeben. Mit der Flash- Message flash[:error] = "Fehlertext" können Sie auch Fehlermeldungen ausgeben.

Flash-Nachrichten müssen immer vor einer Weiterleitung (redirect_to) angegeben werden:

def create
  @bookmark = Bookmark.new(params[:bookmark])
  if @bookmark.save
    flash[:notice] = "Favorit wurde erfolgreich angelegt."
    redirect_to :action => "index"
    ...
  end
end

Flash-Message ausgeben

Damit die Flash-Messages auch angezeigt werden, müssen wir sie in den entsprechenden Views ausgeben. Das könnte die index.html.erb sein, oder für den Fall, dass wir irgendwann einmal auch in anderen Views eine Flash-Message anzeigen wollen, können wir die Ausgabe auch in der application.html.erb vornehmen, da diese für alle Views gültig ist:

Listing  app/views/layouts/application.html.erb

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
  <meta http-equiv="Content-type"
   content="text/html; charset=utf-8">
  <title>Favoritenverwaltung - <%= @title %></title>
  <%= stylesheet_link_tag 'global' %>

</head>
<body>
  <div id="container">
    <div id="header">
      <h1>Meine Linksammlung</h1>
    </div>
    <div id="content">
      <%= flash[:notice] %>
      <%= yield %>
    </div>
  </div>

</body>
</html>

Flash-Message formatieren

Wenn Sie die Ausgabe der Flash-Message formatieren möchten, können Sie in dem Template, in dem die Flash-Nachricht ausgegeben wird, einen Bereich um die Message herum setzen, den Sie dann in der CSS-Datei formatieren können. Damit der Bereich nur dann angezeigt wird, wenn eine Flash-Message gesetzt ist, müssen Sie das Template um eine Abfrage ergänzen, ob eine Flash-Message gesetzt ist.


Rheinwerk Computing - Zum Seitenanfang

Weiterleitungen  Zur nächsten ÜberschriftZur vorigen Überschrift

redirect_to

Weiterleitungen werden eingesetzt, um auf eine andere Website weiterzuleiten oder um eine andere Action aufzurufen. Rails stellt uns dazu die Methode redirect_to zur Verfügung.

Eine Weiterleitung ist dadurch gekennzeichnet, dass sich durch ihren Aufruf in der Regel die URL verändert.

def destroy
  @flight = Flight.find(params[:id])
  @flight.destroy

  respond_to do |format|
    format.html { redirect_to(:action => "index") }
    format.xml  { head :ok }
  end
end

redirect_to("http://www.railsbuch.de")

Um auf eine andere Website weiterzuleiten, übergeben Sie der Methode redirect_to die URL der Website.

redirect_to(:controller => 'countries', :action => 'show', :id => 5)

Um zu einer Action eines anderen Controllers weiterzuleiten, übergeben Sie den Namen des Controllers und der Action. Als zusätzlichen Parameter können Sie z. B. die ID übergeben, die von der Action verarbeitet wird.

redirect_to(:action => 'show', :id => 5)

Wenn Sie zu einer Action des gleichen Controllers weiterleiten möchten, können Sie die Angabe des Controllers weglassen und nur den Namen der Action übergeben. Optional können Sie auch hier weitere Parameter wie die ID übergeben, die von der Action empfangen und verarbeitet werden.

redirect_to(country_url(5))

Wenn Sie zu einer Ressource oder einer benannten Route weiterleiten möchten, können Sie die vom Routing zur Verfügung gestellten Methoden zur Angabe des Pfades nutzen. Im Abschnitt »Routing« in diesem Kapitel erfahren Sie mehr zum Thema Routing.

redirect_to(:back)

Wenn Sie zurück zu der Seite weiterleiten möchten, von der Sie auf die aktuelle Seite gekommen sind, können Sie der Methode redirect_to den Parameter :back übergeben. Die Weiterleitung erfolgt dann zum HTTP_REFERER.

Das ist besonders dann praktisch, wenn z. B. von mehreren Seiten auf ein Formular verlinkt wird und es über den Zurück-Link möglich sein soll, immer zur jeweiligen Vorgängerseite zu gelangen.


Rheinwerk Computing - Zum Seitenanfang

Senden von Dateien und Daten  Zur nächsten ÜberschriftZur vorigen Überschrift

send_file

Streaming

Mit Hilfe der Methode send_file können Sie eine Datei als Datenstrom von jeweils 4.096 Bytes an einen Client-Rechner senden. Das hat den Vorteil, dass nicht erst die ganze Datei vor dem Versenden gelesen werden muss, und macht es deshalb möglich, große Dateien zu senden.

send_file erwartet den Pfad zu der Datei als Parameter:

send_file '/Pfad_zu/Datei.zip'

Achten Sie darauf, diesen Pfad genau zu prüfen, sollte er von einer Website gesendet werden. send_file(params[:path]) erlaubt es sonst unter Umständen einem böswilligen Benutzer, jede Datei auf Ihrem Server herunterzuladen.

Folgende Optionen können angegeben werden:

  • filename:
    Gibt einen Dateinamen-Vorschlag an, der beim Download angezeigt wird.
  • type:
    Setzt den HTTP Content-Type. application/octet-stream ist der Standardwert.
  • disposition:
    Legt fest, ob die Datei angezeigt oder zum Download angeboten werden soll. Mögliche Werte sind inline oder attachment . attachment ist der Standardwert.
  • stream:
    Legt fest, ob die Datei so gesendet werden soll, während sie gelesen wird ( true ), oder ob sie erst ganz gelesen werden soll, bevor sie gesendet wird ( false ). Der Standardwert ist true .
  • buffer_size:
    Legt die Zwischenspeichergröße (in Bytes) für das Streaming fest. Der Standardwert ist 4.096 Bytes.
  • status:
    Legt den Statuscode fest, der mit der Antwort gesendet wird. Der Standardwert ist 200 OK
  • url_based_filename:
    Setzen Sie diese Option auf true , wenn Sie möchten, dass der Browser den Dateinamen zum Speichern der Datei aus der URL liest. Für i18n-Dateinamen ist das in manchen Browsern erforderlich. Die Option filename überschreibt diese Option.
send_file '/Pfad_zur/Datei.pdf',
  :type => 'application/pdf',
  :disposition => 'attachment',
  :filename => 'railsbuch.pdf'

send_data

Binäre Daten senden

Um Daten im Binärformat an einen Client zu senden, steht Ihnen die Methode send_data zur Verfügung. Die Methode erwartet als Parameter die binären Daten.

Folgende Optionen können angegeben werden:

  • filename:
    Gibt einen Dateinamen-Vorschlag an, der beim Download angezeigt wird.
  • type:
    Setzt den HTTP Content-Type. application/octet-stream ist der Standardwert.
  • disposition:
    Legt fest, ob die Datei angezeigt oder zum Download angeboten werden soll. Mögliche Werte sind inline oder attachment . attachment ist der Standardwert.
  • status:
    Legt den Statuscode fest, der mit der Antwort gesendet wird. Der Standardwert ist 200 OK .

Besonders praktisch ist diese Methode, um in der Datenbank binär gespeicherte Bilder im Browser anzuzeigen:

send_data image.data,
  :type => image.content_type,
  :disposition => 'inline'

Rheinwerk Computing - Zum Seitenanfang

Authentifizierung  topZur vorigen Überschrift

Um ein Authentifizierungssystem in Ihrer Applikation einzubinden, haben Sie mehrere Möglichkeiten.

HTTP-Authentifizierung

Mit Hilfe der Methode authenticate_or_request_with_http_basic, die uns ab Rails 2.0 zur Verfügung steht, ist es leicht, eine HTTP-Authentifizierung zu implementieren. Die Methode implementieren Sie im Controller und übergeben ihr einen Block, in dem Sie den Benutzernamen und das Passwort setzen.

Wir haben in Kapitel 3 eine HTTP-Authentifizierung in der Beispielapplikation employees eingesetzt:

Listing  app/controllers/employees_controller.rb

class EmployeesController < ApplicationController
  before_filter :authenticate

  # GET /employees
  # GET /employees.xml
  def index
    @employees = Employee.find(:all)

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @employees }
    end
  end
  ...
  private

  def authenticate
    authenticate_or_request_with_http_basic do |user,password|
      user=="admin" && password=="geheim"
    end
  end

end

before_filter

Durch Aufruf der Methode before_filter :authenticate am Anfang des Controllers bewirken Sie, dass vor dem Ausführen jeder Action des Controllers die Methode authenticate aufgerufen wird. Damit die Methode authenticate nicht von außen aufrufbar ist, haben wir sie als private definiert.

Weitere Informationen zu Filtern und ihrer Funktionsweise erhalten Sie im Abschnitt 9.3.

Plug-in restful_authentication

Das Plug-in restful_authentication stellt zur Zeit als Nachfolger von acts_as_authenticated den De-facto-Standard für die Authentifizierung von Seiten in Rails dar.

Mehr Informationen zu diesem Plug-in, wie Sie es installieren und verwenden, erhalten Sie anhand eines praktischen Beispiels in Kapitel 15.

Ein eigenes Authentifizierungssystem entwickeln

Statt das Plug-in restful_authentication oder die HTTP-Authentifizierung zu nutzen, können Sie natürlich auch ein eigenes Authentifizierungssystem entwickeln. Wie das relativ einfach geht, zeigen wir in Kapitel 5.



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