Daniel Dengler
web developer
Ruby on Rails
Workshop SS 2009
„Ruby on Rails“ and the Rails-Logo are registered trademarks of David Heinemeier Hansson – www.rubyonrails.org
8
Ruby on Rails
ActiveRecord (3)
Routing & REST
ActiveRecord
Finder
Named Scopes
Validierung
Berechnungen
ActiveRecord
Finder
Named Scopes
Validierung
Berechnungen
Find Methode
nd(Primärschlüssel)
nd(Array von Primärschlüsseln)
Find Methode
Project.find(1)
# liefert Projekt mit der id 1
Project.find([1,2])
# liefert Projekte mit den ids 1 und 2
Bedingungen
nd(Typ, :conditions => Conditions)
Typ kann sein:
• : rst (liefert das erste Element)
• :last (liefert das letzte Element)
• :all (liefert alle Elemente)
Conditions können sein:
• String
• Array
• Hash
Bedingungen
Project.find(:first, :conditions => \"title = 'one'\")
# ACHTUNG: Kein vordefinierter Schutz gegen SQL-Injections
# bei der Verwendung von Strings
Project.find(:first, :conditions => [\"title = ?\", \"one\"])
Project.find(:first, :conditions => {:title => \"one\"})
Kurzformen
nd(Typ, Optionen)
Typ kann ersetzt werden durch:
• rst(Optionen)
• last(Optionen)
• all(Optionen)
Sortieren
Project.all(:order => \"title\")
# Alle Projekte aufsteigend nach Titel sortiert
Project.all(:order => \"title DESC\")
# Alle Projekte absteigend nach Titel sortiert
Project.all(:order => \"title DESC, created_at ASC\")
# Alle Projekte absteigend nach Titel und aufsteigend
# nach Erstellungsdatum sortiert, falls doppelt vorhanden
Limitierung und Versatz
Project.all(:limit => 10)
# liefert max. 10 Projekte
Project.all(:limit => 10, :offset => 10)
# liefert max. 10 Projekte beginnend bei dem 10.
N + 1 Problem
Es wird eine Operation auf einer Relation
ausgeführt und damit für jedes Objekt
eine neue Datenbankabfrage generiert.
N + 1 Problem
@project = Project.all
@project.each do |p|
puts p.tasks.collect {|t| t.title}
# Lädt beim Aufruf jeweils ein Objekt
end
# Anzahl der Queries:
# 1 Query für das holen aller Projekte
# + jeweils 1 Query für jedes Projekt, dem
# Tasks zugeordnet sind!
N + 1 Problem
@project = Project.all(:include => [:task] )
@project.each do |p|
puts p.tasks.collect {|t| t.title}
end
# Anzahl der Queries:
# 1 Query für das holen aller Projekte
# 1 Query für alle Tasks
Dynamische Finder
ActiveRecord erkennt besondere Finder
am Funktionsnamen:
• nd_by_title
• nd_all_by_project_id_and_completed
Dynamische Finder
Project.find_by_title 'Rails Workshop'
Task.find_all_by_project_id_and_completed 1, true
ActiveRecord
Finder
Named Scopes
Validierung
Berechnungen
Named Scopes
De nieren gekapselte Abfragebedingungen,
die häu g verwendet werden.
Named Scopes
class Task < ActiveRecord::Base
named_scope :completed, :conditions => ['completed = ?', true]
named_scope :open, :conditions => ['completed = ?', false]
named_scope :high_prio, :conditions => {:priority => \"high\"}
end
Task.completed # liefert alle abgeschlossenen Tasks
Task.open # liefert alle offenen Tasks
Task.open.high_prio # liefert alle offenen Tasks mit hoher Priorität
Default Scope
class Task < ActiveRecord::Base
default_scope :order => 'completed DESC, title'
end
Task.all # liefert alle Projekte entsprechend sortiert
Named Scopes
Vorsicht bei dynamischen
Abfragebedingungen, da diese gecached
werden!
Näheres siehe Dokumentation zu
ActiveRecord::NamedScope::ClassMethods
ActiveRecord
Finder
Named Scopes
Validierung
Berechnungen
Eingabevalidierung
Eingabevalidierung
class Project < ActiveRecord::Base
validates_presence_of :title
end
Vorde nierte Validierungen
validates_acceptance_of Feld
• prüft, ob ein bestimmtes Feld gesetzt
wurde
Beispiel:
Zustimmung zu den AGBs
Vorde nierte Validierungen
validates_associated Model
• führt die Validierungen eines
verknüpften Modells (etwa
has_many :tasks) mit aus
Vorde nierte Validierungen
validates_con rmation_of Feld
• benötigt ein zusätzliches Feld mit der
Bezeichnung Feldname_con rmation
• prüft, ob ein Feld wiederholt korrekt
eingegeben wurde
Beispiel:
Passwortwiederholung
Vorde nierte Validierungen
validates_exclusion_of Feld, :in => Array
• der Wert darf nicht im de nierten Array
vorkommt
Beispiel:
Nutzer kann Subdomain bekommen und
darf bestimmte Varianten, wie www, imap
oder smtp nicht wählen
Vorde nierte Validierungen
validates_format_of Feld, :with => Regexp
• prüft, ob der Wert die Anforderungen
der Regular Expression erfüllt
Beispiel:
Validierung von E-Mail-Adressen
Vorde nierte Validierungen
validates_inclusion_of Feld, :in => Array
• der Wert muss in einem de nierten
Array vorkommen
Beispiel:
Priorität einer Aufgabe kann nur
bestimmte Werte annehmen
Vorde nierte Validierungen
validates_length_of Feld, Optionen
• prüft die Länge eines Wertes
Optionen:
• :maximum => Integer
• :minimum => Integer
• :in => Range (etwa 6..10)
• :is => Integer
Vorde nierte Validierungen
validates_numericality_of Feld, Optionen
• prüft, ob es sich bei dem Wert um
eine Zahl handelt
• prüft die Grenzen des Zahlenwertes
Optionen:
• siehe Dokumentation
Vorde nierte Validierungen
validates_presence_of Feld
• prüft, ob das Feld gefüllt wurde
Beispiel:
• Projekte benötigen einen Titel
Vorde nierte Validierungen
validates_uniqueness_of Feld
• prüft, ob das Feld eindeutig ist, also
nicht bereits in der Datenbank
vorkommt
Beispiel:
• Der Titel eines Projektes muss eindeutig
sein
ActiveRecord
Finder
Named Scopes
Validierung
Berechnungen
Berechnungen
Project.count # liefert Anzahl der Projekte
Project.count(:conditions => {:completed => false})
# liefert Anzahl der Projekte, die abgeschlossen sind
Project.maximum(\"duration\")
Project.minimum(\"duration\")
Project.average(\"duration\")
Project.sum(\"duration\")
# liefern die maximale, minimale, durchschnittliche
# oder gesamte Dauer der Projekte
Routing & REST
MVC Rails
MVC Rails
Routing
Aufgaben des Routings:
• Eine HTTP-Anfrage an eine URL in
den Aufruf einer Methode in einem
Controller verwandeln
• URLs aus de nierten Parametern
generieren, damit dies nicht von
Hand erfolgen muss
con g/routes.rb
• Enthält die De nition der Routen
• Wird von oben nach unten
abgearbeitet -> erste zutreffende
Route wird verwendet und weitere
Routen werden nicht mehr
betrachtet
Standard Routen
map.connect ':controller/:action/:id'
URL: /projects/show/1
map.connect ':controller/:action/:id.:format'
URL: /projects/show/1.xml
Reguläre Routen
map.connect 's/:action', :controller => 'static'
URL: /s/imprint
Weitere Optionen siehe API
Benannte Routen
map.imprint 'imprint', :controller =>
'static', :action => 'imprint'
URL: /imprint
GENERATOREN: imprint_path, imprint_url
Weitere Optionen siehe API
REST
Representational State Transfer
Grundprinzipien
• URL als Identi kator einer Resource
• HTTP-Methode als Aktion
Verwendete HTTP-Methoden
GET - Bestehende Resource zurückgeben
POST - Neue Resource erstellen
PUT - Bestehende Resource ändern
DELETE - Bestehenden Resource löschen
RESTful Routes
map.resources :projects
RESTful Routes
RESTful Routes
GET /projects - Projektliste liefern
RESTful Routes
GET /projects - Projektliste liefern
GET /projects/1 - Projekt mit der ID 1 liefern
RESTful Routes
GET /projects - Projektliste liefern
GET /projects/1 - Projekt mit der ID 1 liefern
GET /projects/new - Formular für neues Projekt
RESTful Routes
GET /projects - Projektliste liefern
GET /projects/1 - Projekt mit der ID 1 liefern
GET /projects/new - Formular für neues Projekt
POST /projects - Neues Projekt erstellen
RESTful Routes
GET /projects - Projektliste liefern
GET /projects/1 - Projekt mit der ID 1 liefern
GET /projects/new - Formular für neues Projekt
POST /projects - Neues Projekt erstellen
GET /projects/1/edit - Formular zum Bearbeiten
RESTful Routes
GET /projects - Projektliste liefern
GET /projects/1 - Projekt mit der ID 1 liefern
GET /projects/new - Formular für neues Projekt
POST /projects - Neues Projekt erstellen
GET /projects/1/edit - Formular zum Bearbeiten
PUT /projects/1 - Ändern des Projektes
RESTful Routes
GET /projects - Projektliste liefern
GET /projects/1 - Projekt mit der ID 1 liefern
GET /projects/new - Formular für neues Projekt
POST /projects - Neues Projekt erstellen
GET /projects/1/edit - Formular zum Bearbeiten
PUT /projects/1 - Ändern des Projektes
DELETE /projects/1 - Löschen des Projektes
RESTful Routes
GET /projects - projects_path
GET /projects/1 - project_path(1)
GET /projects/new - new_project_path
POST /projects - projects_path
GET /projects/1/edit - edit_project_path(1)
PUT /projects/1 - project_path(1)
DELETE /projects/1 - project_path(1)
Nested Routes
map.resources :projects do |project|
project.resources :tasks
end
project_tasks_path(1)
URL: /projects/1/tasks
project_task_path(1,1)
URL: /projects/1/tasks/1
Formate
respond_to do |format|
format.html # return the default template for HTML
format.xml { render :xml => @project.to_xml }
end
0 comments
Post a comment