Warning: include_once(/var/www/html/pmwiki-2.2.86/cookbook/soap4pmwiki/soap4pmwiki.php): failed to open stream: No such file or directory in /var/www/html/fields/dbp11/local/config.php on line 4

Warning: include_once(): Failed opening '/var/www/html/pmwiki-2.2.86/cookbook/soap4pmwiki/soap4pmwiki.php' for inclusion (include_path='.:/opt/php/lib/php') in /var/www/html/fields/dbp11/local/config.php on line 4

Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/fields/dbp11/local/config.php:4) in /var/www/html/pmwiki-2.2.86/pmwiki.php on line 1250
Datenbankpraktikum SS 2011 - Controller - Konkret

Die Umsetzung im Detail

Jede Controllerklasse ist in ihrem Grundgerüse gleich. Sie erbt vom ApplicationController und ist mit den, bereits oben beschriebenen CRUD Operationen ausgestattet. Damit wir nur angemeldeten Nutzern den Zugang zu unserer Webanwenung erlauben, haben wir in jede Klasse einen before_filter integriert. Außerdem verfügen alle Klassen, außer dem RatingsController, über ein load_and_authorize_resource Statement, um die Berechtigungen des einzelnen Nutzers für die unterschiedlichen Methoden zu überprüfen, dazu aber in IV.b. mehr. Im Kopf des Controllers finden wir außerdem zwei bis drei Exception Handler, die u.a. die CanCan Exceptions oder die Standardexceptions fangen und die Fehlermeldung in eine für den Anwender leserliche Form wiedergeben.

Messages

Der erste Teilbereich auf den ich jetzt hier eingehen möchte, ist unser Nachrichtensystem, bzw. den dafür zuständigen MessagesController. Nach Konsultation mit der View Gruppe, waren wir uns über die Features des Nachrichtensystems einig. Folgendes sollte umgesetzt werden:

  • Anzahl der noch ungelesenen Nachrichten
  • Übersicht über geschriebene Nachrichten
  • Eine „Antworten-Funktion“
  • Nachricht löschen
  • Nachricht einen Trip betreffend

Nachdem wir uns einig waren, wie unser Nachrichtensystem funktionieren sollte, besprachen wir uns mit dem Model, damit die für uns notwendigen Datenfelder und Funktionen integriert werden konnten. In der index Methode des Controllers stellten wir der View dann eine Liste mit den Nachrichten des aktuellen Nutzers, und die Anzahl der noch ungelesenen Nachrichten zur Verfügung, außerdem ein Zeitstempel, der angibt, wann der Nutzer zuletzt sein Postfach abgerufen hat. So konnten im Template diejenigen Nachrichten, die einen Zeitstempel haben, der vor dem des letzten Aufrufs des Postfaches liegt, als ungelesenen markiert werden. Um den Zeitstempel aktuell zu halten wurde dieser anschließend noch auf die aktuelle Zeit gesetzt. Die new Methode passten wir so an, das sie die gewünschten Funktionalitäten erfüllt, indem wir drei mögliche Parameter von der View berücksichtigen, die wir per GET Request bekommen. Je nachdem, welchen Parameter wir bekommen, bearbeiten wir das Message-Objekt, indem wir den Empfänger setzen oder den Betreff automatisch mit einem Link zu der Fahrt befüllen, den die Nachricht betrifft. Das Löschen einer Nachricht gestaltete sich schwieriger als bei den anderen Objekten, da wir nicht einfach die destroy Methode aufrufen konnte. Da unser Nachrichten Objekt in der Datenbank nur einmal vorhanden ist, aber sowohl vom Autor als auch vom Empfänger gelesen wird, können wir, wenn nur einer von beiden die Nachricht löscht, sie nicht einfach entfernen, da sie sonst auch für die Gegenseite nicht mehr sichtbar ist. Um dieses Problem zu lösen, wurde ein weiteres Datenfeld eingefügt, welches die Sichtbarkeit der Nachricht für den Autor, bzw. den Empfänger regelt. Der „Löschvorgang“ wurde dann eher als eine Art Update implementiert, indem das Sichtbarkeitsfeld der entsprechenden Nachricht geändert wurde. Wird hierbei festgestellt, dass sowohl Autor als auch Empfänger die Nachricht gelöscht haben, wird sie entgültig aus der Datenbank entfernt. Beispielhaft ist hier der Codeausschnitt der update-Methode zu sehen, die den „Löschvorgang“ realisiert.

  def update
    @message = Message.find(params[:id])
    # "Loescht" der Empfaenger eine Nachricht, wird sie fuer ihn invisible
  	if params[:who] == "receiver"
	  	@message.delete_receiver = true
    # "Loescht" der Schreiber eine Nachricht, wird sie fuer ihn invisible
  	elsif params[:who] == "writer"
	  	@message.delete_writer = true
  	end
    @message.save
    # Haben Autor und Empfaenger einer Nachricht sie "geloescht" wird sie auch richtig aus der DB entfernt
	  if @message.delete_receiver and @message.delete_writer
  	   @message.destroy
  	end

Trips

Da der Kernpunkt unserer Anwendung aber ja die Fahrten sind, die angeboten werden, haben wir die meißte Zeit in diesen Bereich investiert. Folgende Ideen wurde dazu entwickelt:

  • Übersicht über meine Fahrten (Kommende und absolvierte)
  • Detailansicht einer Fahrt
  • Je nach Status unterschiedliche Berechtigungen
    • Bewerbungen, Annehmen, Ablehnen, Nachricht schicken, Rating abgeben, wenn Fahrt vorbei
  • Beim Fahrt erstellen Start und Zieleingaben anhand eines Eingabefeldes
  • Fahrt kann abgesagt werden, wenn sie noch nicht absolviert wurde

Die Übersicht über meineFahrten wurde wieder in der index Methode realisiert, indem wir aus der Datenbank, mithilfe der Methoden des Models, die entsprechenden Datensätze holen und sie an die View übergeben. Hier wird noch unterschieden, ob ich Admin Berechtigungen haben oder nicht. Sollte dies der Fall sein, werden mir nicht nur meine, sondern alle Fahrten zur Verfügung gestellt. Die Detailansicht eine Fahrt gestaltet sich schwieriger, weil mir mit den bisherigen Rollen des Member und des Admins nicht untescheiden konnte, ob ich Fahrer einer Fahrt bin oder ich mich auf ebendiese bewerben kann. Gelöst haben wir dieses Problem indem wir spezielle „Konstanten“ eingeführt haben, die meine jeweilige Rolle beschreiben und mir dementsprechende Rechte zuweisen. Rufe ich die Detailansicht einer Fahrt auf, wird zuerst mein Status überprüft, welches mithilfe einer ausgelagerten Methode geschieht. Neben weiteren Variablen für die freien und bereits besetzten Plätze der Fahrt überprüfen wir ob der Nutzer uns weitere Parameter mitsendet, die wir dann entsprechend behandeln mussten. So können wir eine neue Bewerbung für die Fahrt, oder eine Annahme, bzw. eine Ablehung oder Austragung realisieren. Sollte dieser Parameter erkannt werden, wird noch überprüft, ob der Nutzer dazu überhaupt berechtigt ist, zB. Sollte ein Mitfahrer nicht dazu in der Lage sein, andere Bewerben anzunehmen oder abzulehnen, dies ist nur dem Fahrer vorbehalten. Als Besonderheit wird bei allen Anfragen eines Nutzers, sei es eine Bewerbung oder eine Annahme durch den Fahrer automatisch eine Nachricht verschickt. So wird der Bewerber auf eine Fahrt automatisch über das Nachrichtensystem benachrichtigt, wenn er angenommen, bzw. abgelehnt wurde. Bei der Erstellung einer Fahrt wird, wird zur Start -und Zieleingabe nur jeweils ein Eingabefeld angeboten, um es dem Nutzer einfacher zu machen, seine Wünsche einzutragen. Hier kommt es allerdings zu einer Diskrepanz zwischen Nutzereingabe und dem, was die Datenbank erwartet. Innerhalb der Datenbank ist es aus datentechnischen Gründen notwendig, die Start -und Zieleingabe in jeweils drei Datenfeldern zu speichern. Um dieses Problem zu bewältigen wird bei der Erstellung einer Fahrt zuerst anhand der Benutzereingabe mittels des Geocoders jeweils ein Paar von Koordinaten für den Start -und Zielpunkt ermittelt, diese werden dann in das Objekt eingetragen. Um die Daten in die notwendigen drei Teile aufzusplitten, nutzen wir hier eine vom Model zur Verfügung gestellte Methode, die am aktuellen Fahrten-Objekt aufgerufen wird und es passend modifiziert. Ein weiteres Problem, das von uns gelöst werden musste, ergab sich bei der Eingabe der gewünschten Abfahrtszeit. Von der View bekommen wir 5 Parameter übergeben, die in der Datenbank allerdings in einem Datenfeld gespeichert werden. Wir konnten diesen Konflikt leicht beseitigen indem wir die Eingaben einfach in der syntaktisch richtigen Form aneinanderfügen.

Requests

Der Gegenpart zur Fahrt ist in unserer Anwendung die „Anfrage“, oder auch der „Request“. Anstatt einer Suche, in der mir alle passenden Fahrten ausgegeben werden, erstellen wir Anfragen, die persistent in unserer Datenbank gespeichert werden. Im Vergleich zu den Fahrten war die Umsetzung unserer Ideen bezüglich der Anfragen recht einfach. Es sollte möglich sein, uns alle unsere Anfragen anzuzeigen, und davon eine in Detailansicht anzuschauen, in der dann wiederum passende Fahrten auf eben diese Anfrage aufgelistet werden. Die Umsetzung ebendieser Übersichts -und Detailansicht erfolgte analog zu denen der Fahrten. Die passenden Trips zu unserer Anfrage beschaffen wir uns mithilfe einer vom Model zur Verfügung gestellten Methode. Auch die Erstellung von Anfragen passiert fast analog zur Fahrtenerstellung, indem wie aus einer Nutzereingabe die Koordinaten bestimmen und sie vom Model in drei Teile splitten lassen.

Ratings

Ein weiterer wichtiger Punkt, ist das Bewertungssystem. Es sollte möglich sein, für jede Fahrt an der ich teilgenommen habe, den Fahrer und meine Mitfahrer zu bewerten. Wie bei den anderen Controllern wurde wieder eine Übersicht über meine Ratings integiert, und wir geben eine Variable an das Template weiter, welches meine, noch ausstehenden Ratings enthält. Innerhalb der show Methode lassen sich, anhand einer übergeben id, die Ratings des, dem der id zugehörigen Nutzers anzeigen. Dies ist standardmäßig der aktuell eingeloggte Nutzer, jedoch kann es ebenso von Interesse sein, die Bewertungen des Fahrers zu überprüfen an dessen Fahrt ich teilnehmen möchte. Die show erlaubt in diesem speziellen Fall keine Detailansicht eines einzelnen Ratings, sondern erfüllt eine ähnliche Funktion wie die index Methode. Ähnlich wie beim Message Controller prüfen wir auf neue Ratings und setzen gegebenenfalls den Zeitstempel auf die aktuelle Zeit.


Page last modified on August 21, 2011, at 07:36 PM