10.13 Callbacks

ActiveRecord bietet einen sehr hohen Komfort, indem zu jeder Model-Klasse Methoden zum Hinzufügen, Ändern, Löschen usw. automatisch zur Verfügung gestellt werden. Man muss lediglich eine Tabelle (über eine Migration) erstellen und gegebenenfalls ein paar Deklarationen für Assoziationen in der entsprechenden Model-Klasse definieren.
Beispiele
In einigen Anwendungsfällen reicht es nicht aus, dass bei Aufruf der Methode destroy nur der entsprechende Datensatz gelöscht wird. Bei einer Produkt-Tabelle, in der Produktbilder und PDF-Broschüren nicht in der Datenbank, sondern als Dateien abgelegt sind, wäre es sinnvoll, dass der Aufruf der destroy -Methode nicht nur den entsprechenden Datensatz, sondern auch die zugehörigen Dateien löscht.
Anstatt jedoch eine eigene destroy -Methode zu implementieren, können sogenannte Callbacks definiert werden. Mittels Callbacks können Sie ActiveRecord anweisen, Ihren eigenen Code vor oder nach Ausführung von bestimmten Befehlen, wie speichern, löschen usw., auszuführen. In unserem Beispiel können wir einen Callback erstellen, der nach dem Löschen des Datensatzes mit destroy die zugehörigen Dateien löscht.
class Product < ActiveRecord::Base after_destroy :delete_pdf_files private def delete_pdf_files # Lösche Dateie FileUtils.rm(pdf_path) end end
In dem Beispiel wird nach jedem Aufruf der destroy -Methode die Methode delete_pdf_files aufgerufen.
Datensatz nicht löschen
Im folgenden Beispiel soll beim Aufruf der Methode destroy nicht der Datensatz aus der Datenbank entfernt werden, sondern nur ein Feld gesetzt werden, das den Datensatz als gelöscht markiert. Dies ist z. B. bei Daten sinnvoll, die für Recherche-Zwecke immer verfügbar sein müssen.
Zum Markieren wird ein Feld deleted_at verwendet, das die aktuelle Uhrzeit und das aktuelle Datum zum Zeitpunkt des Löschens enthält. Ist das Feld leer, so wurde der Datensatz nicht gelöscht.
class Flight < ActiveRecord::Base before_destroy :mark_as_deleted ... private def mark_as_deleted # setze deleted_at auf die aktuelle Uhrzeit und Datum update_attribute(:deleted_at, Time.now) # ist Rückgabewert false, bricht Ausführung # der destroy-Methode ab. return false end end
:conditions
Um alle Datensätze, die nicht als gelöscht markiert sind, abzufragen, muss in der find -Methode eine entsprechende Bedingung (:conditions) angegeben werden.
Liste von Callbacks
Methoden
In der folgenden Liste werden die verschiedenen Callback-Methoden aufgeführt.
- before_validation
Callback wird vor einer Validierung ausgeführt.
- after_validation
Callback wird nach einer Validierung ausgeführt.
- before_validation_on_create
Callback wird vor einer Validierung eines neuen Datensatzes ausgeführt.
- after_validation_on_create
Callback wird nach einer Validierung eines neuen Datensatzes ausgeführt.
- before_save
Callback wird vor dem Speichern ausgeführt.
- after_save
Callback wird nach dem Speichern ausgeführt.
- before_create
Callback wird vor Ausführung der create -Methode ausgeführt.
- after_create
Callback wird nach Ausführung der create-Methode ausgeführt.
Markieren eines gelöschten Datensatzes mit einem Plug-in |
Für diesen Zweck kann auch das Plug-in acts_as_paranoid eingesetzt werden, das auch ein Feld deleted_at zur Markierung gelöschter Datensätze verwendet. Die Installation erfolgt mit folgendem Befehl:
script/plugin install http://railsbuch.de/urls/30 In der Model-Klasse muss nur die Methode acts_as_paranoid aufgerufen werden. Es muss kein eigener Callback definiert werden. class Flight < ActiveRecord::Base acts_as_paranoid end Die zugehörige Tabelle benötigt ein Feld deleted_at . Das Plug-in hat die Methoden find und count so angepasst, dass nur die nicht gelöschten (markierten) Datensätze einbezogen werden. Außerdem stellt das Plug-in die Methoden find_with_deleted und count_with_deleted zur Verfügung, bei denen die als gelöscht markierten Datensätze einbezogen werden. |
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.