Frage

Ich mag die Aktionen des Benutzers in meiner Ruby on Rails-Anwendung anmelden.

Bisher Ich habe ein Modell Beobachter, die Protokolle in der Datenbank nach Updates und erstellt einfügt. Um die Benutzer zu speichern, der die Aktion ausgeführt, die protokolliert wurde, brauche ich Zugriff auf die Sitzung, aber das ist problematisch.

Zum einen bricht es das MVC-Modell. Zweitens reiche Techniken aus dem hackish zum abwegig, vielleicht vielleicht sogar die Umsetzung an den Server Mongrel zu binden.

Was ist der richtige Weg zu nehmen?

War es hilfreich?

Lösung

Das finde ich eine sehr interessante Frage zu sein. Ich gehe aus denken laut hier einen Moment ...

Schließlich, was wir konfrontiert mit ist eine Entscheidung, ein Design-Muster akzeptable Praxis, um zu verletzen, eine bestimmte Gruppe von Funktionalität zu erreichen. Also, wir müssen uns fragen,

1) Was sind die möglichen Lösungen, die würden nicht MVC-Muster verletzen

2) Was sind die möglichen Lösungen, die würde verletzen das MVC-Muster

3) Welche Option ist am besten? Ich halte Design-Muster und Standardpraktiken sehr wichtig, aber zur gleichen Zeit, wenn sie halten macht den Code komplexe, dann die richtige Lösung kann sehr gut sein, um die Praxis zu verletzen. Einige Leute könnten nicht einverstanden mit mir auf, dass.

Lets # 1 zunächst prüfen.

Aus der Spitze von meinem Kopf, ich würde denken, der folgenden möglichen Lösungen

A) Wenn Sie wirklich daran interessiert sind, die diese Aktionen ausführen, sollten diese Daten jede Art und Weise in dem Modell gespeichert werden? Es würde diese Informationen zur Verfügung zu Ihrem Observer machen. Und es bedeutet auch, dass andere Front-End-Anrufer Ihrer Active Klasse die gleiche Funktionalität wird.

B) Wenn Sie Verständnis nicht wirklich daran interessiert sind, die einen Eintrag erstellt, aber mehr daran interessiert, die Protokollierung der Web-Aktionen selbst, dann könnten Sie „beobachten“ die Controller-Aktionen in Betracht ziehen. Es ist einige Zeit her, dass ich um Rails Quelle gestoßen habe, so bin ich nicht sicher, wer ihre Active :: Observer „beobachtet“ das Modell, aber man könnte es zur Anpassung an einen Controller Beobachter können. In diesem Sinne beobachten Sie das Modell nicht mehr, und es macht Sinn Sitzung und andere Controller-Typen Dateninformationen zu diesem Beobachter zu machen. C) Die einfachste Lösung, mit der geringsten „Struktur“, ist einfach Ihren Logging-Code am Ende der Aktionsmethoden fallen, die Sie gerade sehen.

Betrachten Option # 2 jetzt, bricht MVC Praktiken.

A) Wie Sie vorschlagen, Ihnen die Mittel, um Ihr Modell Observer finden konnten, zu bekommen Zugriff auf die Session-Daten zu haben. Sie haben Ihr Modell auf Ihre Business-Logik gekoppelt ist.

B) kann nicht von irgendwelchen anderen hier:)

Meine persönliche Neigung, ohne zu wissen, mehr Details über Ihr Projekt ist entweder 1A, wenn ich die Leute auf Datensätze anhängen möchten, oder 1C, wenn es nur wenige Orte, wo ich dabei daran interessiert bin. Wenn Sie wirklich eine robuste Logging-Lösung für alle Controller und Aktionen wollen, könnten Sie 1B betrachten.

Mit Ihrem Modell Beobachter Sitzungsdaten finden, ist ein bisschen „stinkende“, und würde wahrscheinlich brechen, wenn Sie versucht haben, Ihr Modell in einem anderen Projekt / Lage / Kontext zu verwenden.

Andere Tipps

HRM, ist dies eine schwierige Situation. Sie haben ziemlich viel zu MVC verletzen es schön zum Laufen zu bringen.

ich so etwas tun würde:

class MyObserverClass < ActiveRecord::Observer
  cattr_accessor :current_user # GLOBAL VARIABLE. RELIES ON RAILS BEING SINGLE THREADED

  # other logging code goes here
end

class ApplicationController
  before_filter :set_current_user_for_observer

  def set_current_user_for_observer
    MyObserverClass.current_user = session[:user]
  end
end

Es ist ein bisschen hacky, aber es ist nicht mehr Hacky als viele andere Kernschienen Dinge, die ich je gesehen habe.

Alles, was Sie tun müssen, würde es THREAD (diese Dinge nur, wenn Sie auf jruby laufen sowieso) zu machen, ist die cattr_accessor zu ändern, um eine geeignete Methode zu sein, und haben sie es die Daten in Thread-lokalen Speicher speichern

Sie haben recht es MVC zu brechen. Ich würde vorschlagen, Rückrufe in Ihren Controller verwenden, vor allem, weil es gibt Situationen (wie ein Modell, das genannt speichern, aber nicht Validierung), wo Sie sich einen Beobachter Anmeldung etwas nicht wollen.

fand ich eine saubere Art und Weise zu tun, was von der Antwort wird vorgeschlagen, nahm ich.

http://pjkh.com / articles / 2009/02/02 / Erstellen von-ein-Audit-log-in-Schienen

Diese Lösung verwendet ein auditlog Modell sowie einen trackchanges Modul Tracking-Funktionalität zu jedem Modell hinzuzufügen. Es bedarf noch der Sie eine Zeile an den Controller hinzuzufügen, wenn Sie allerdings aktualisieren oder erstellen.

In der Vergangenheit, als so etwas wie dies zu tun, ich habe in Richtung Erweiterung der User-Modell Klasse neigten dazu, die Idee des "aktuellen Benutzers enthalten

zu den bisherigen Antworten der Suche, ich sehe Vorschläge, um die eigentlichen aktiven Rekord Benutzer in der Sitzung zu speichern. Dies hat mehrere Nachteile.

  • Er speichert ein möglicherweise großes Objekt in der Sitzungs-Datenbank
  • Es bedeutet, dass die Kopie des Benutzers für alle Zeit ‚zwischengespeichert‘ wird (oder bis zum Logout gezwungen). Das bedeutet, dass Änderungen in den Status dieses Benutzers nicht erkannt werden, bis sich der Benutzer abmeldet und meldet sich zurück. Das bedeutet zum Beispiel, dass der Benutzer ihn abzumelden wird warten zu deaktivieren versucht und wieder ein. Dies ist wahrscheinlich nicht das Verhalten, das Sie wollen.

So, dass zu Beginn einer Anfrage (in einem Filter) nehmen Sie die user_id aus der Sitzung und lesen Sie den Benutzer, das Setzen von User.current_user.

So etwas ...

class User
  cattr_accessor :current_user
end

class Application
  before_filter :retrieve_user

  def retrieve_user
    if session[:user_id].nil?
      User.current_user = nil
    else
      User.current_user = User.find(session[:user_id])
    end
  end
end

Von nun an sollte es trivial sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top