Hurra, es ist vollbracht! Nach zwei Tagen des frustgeladenen Programmierens bis in die späten Morgenstunden hinein scheint meine Transaktions-API nun relativ solide geworden zu sein. Es haben sich einige Änderungen gegenüber dem ergeben, was ich bereits in meinem letzten Eintrag zu dem Thema schrieb. Doch alles der Reihe nach:
- Der gesamte Transaktionsrelevante Code liegt jetzt in einem eigenen Modul:
Consolvix::TransactionAPI
. Wenn also nun ein Controller für gewisse Aktionen Transaktionsfunktionalität braucht, kann er diese überinclude Consolvix::TransactionAPI
einbinden. - Um einen aus mehreren Schritten aufgebauten Transaktionshandler zu erstellen, dient die methode
transaction_handler
. Diese generiert aus den angegebenen Daten alle Unterschritte und Überpfügungsmethoden als Stubs. - das Laden und Speichern der aktuellen Transaktion geschieht automagisch über in
transaction_handler
eingefügte before- bzw. afterfilter (Danke an Daniel für die Zeit die du dir genommen hast, nach dem Gepräch hat's irgendwie funktioniert -- darüber reden hilft oft schon g) - um die korrekte Weiterleitung an die richtigen actions kümmert sich der beim Aufruf von
transaction_handler
generierte Code ebenfalls vollständig selbst, im Wesentlichen immer noch so wie im letzten Eintrag beschrieben. Nur eben schön versteckt für den Programmierer. Die Einzige wichtige Änderung, die sich ergeben hat, ist dass die Schrittnummer jetzt als parameter und nicht mehr als ID-Teil der URI mitgegeben wird -- aus dem Grunde, weil z.B. eine "bearbeite Kunde soundsoviel" eine ID-Angabe benötigt...
Nehmen wir nun also an, im HostingAccountsController
sollen die beiden Aktionen new
und edit
als mehrschrittige Transaktion ausgeführt werden. Dazu definiere man dann zuerst das Folgende:
class HostingAccountsController < ApplicationController
transaction_handler 'Edit Hosting Account',
:edit,
:worker => :update,
:selector => :select_update_transaction
1 => [:edit_step1, nil],
2 => [:edit_step2, :step1_done?],
3 => [:edit_step3, :step2_done?],
4 => [:edit_save, :step4_done?]
transaction_handler 'Create Hosting Account for existing Client',
:new,
:worker => :create,
1 => [:cha_step1, nil],
2 => [:cha_step2, :step1_done?],
3 => [:cha_step3, :step2_done?],
4 => [:cha_save, :step4_done?]
end
Die Argumente bedeuten folgendes:
- Menschenlesbare Beschreibung, die z.B: beim Auswählen unfertiger Transaktionen angezeigt wird.
- Name der Haupt-Aktion = "Name der Transaktion", im folgenden
main_action
genannt. Diese erstellt eine neue Transaktion und leitet anschließend an dieworker_action
weiter. - :worker (optional, default = "do#{mainaction}"): die Aktion, an die im späteren Verlauf jeweils alle Daten gesendet werden, unter Angabe des aktuellen Schrittes.
- :selector (optional, default = "selecttransact#{main_action}"): die Aktion, die aufgerufen wird wenn keine (gültige) Transaktions-ID an die
worker_action
übergeben wurde UND wenn mehrere Transaktionen des verlangten Typs offen sind.
- 1...n => [action, prerequisite]: dieser hash hat als Schlüsel die Schritt-Nummer und als Wert den Namen des auszuführenden Unterschrittes sowie seine Vorbedingung, die erfüllt sein soll. Die hier angegebenen tatsächlichen Unterschritte der Transaktion sind protected und nicht direkt aufrufbar. Der Zugriff wird über die
worker_action
geregelt, die bei jedem Aufruf prüft, ob zur Aufgerufenen Schritt-Nummer auch die Vorbedingung erfüllt ist. Vorbedingungen sind Methoden, die einen boolean-Wert zurück geben. Wenn sie nicht in der Controller-Klasse explizit implementiert werden, dan werden die vordefinierten Stubs aufgerufen, die immer FALSE liefern -- so merkt man als Entwickler schnell mal, dass man was vergessen hat zu implementieren ;-)
Für die ganz harten unter der werten Leserschaft dieses Blogs hänge ich gleich mal den Code von TransactionAPI an. Wer die Muße hat, ihn durchzulesen und zu verstehen (müsste machbar sein, er ist sogar kommentiert ;-)) und mir dazu Ideen und Verbesserungsvorschläge oder einfach nur fiese Detailfragen zu stellen, der sei an dieser Stelle herzlich dazu eingeladen.
Comments (1)
Freut mich, in irgendeiner Weise doch geholfen zu haben. ;-)
Deinen Code hatte ich ja schon...da werde ich dann ggf. mal reingucken, wenn ich mal 'ne Methode brauche, die mir 'ne Methode generiert, die dann ne Methode generiert! ;-)
So. Gute Nacht!
Posted by Daniel | December 13, 2007 11:25 PM
Posted on December 13, 2007 23:25