2009-05-09 7 views
2

Ich verwende eine hässliche Muster in meinem Code und ich weiß, es muss eine bessere Möglichkeit, dies zu tun. Hilf mir zu überdenken, was ich tue.Übergeben von Daten zwischen den Controllern mit der Sitzung RESTvoll

Meine Website ist eine Art Diskussionsforum. Alle Antworten auf Diskussionen werden auf der DiscussionsController # show-Seite inline ausgeführt.

Einige Antworten sind jedoch ungültig. Wenn Sie beispielsweise versuchen, eine Antwort ohne Text einzugeben, werden Sie mit einer Fehlermeldung an DisconsualsController # show zurückgegeben.

Hier ist ein kurzer Überblick, wie ich diesen Workflow implementiert haben:

  1. Benutzer geht zu DiscussionsController # show. Diese Vorlage hat ein Antwortformular darauf. Es gibt keine explizite RepliesController # neue Aktion.
  2. Der Benutzer sendet ein Antwortformular, das an replys_path gesendet und in RepliesController # create behandelt wird.
  3. AntwortenController # create kann die Antwort nicht speichern, da sie ungültig ist (validates_length_of in Reply deaktiviert das Objekt).
  4. AntwortenController # create stellt das Antwortobjekt in die Sitzung [: new_reply] und leitet den Diskussionspfad weiter, von dem der Benutzer kam.
  5. DiscussionsController # show behandelt das Sitzungsobjekt ...

Wie so:

if session[:new_reply] 
    @new_reply = session[:new_reply] 
    session.delete(:new_reply) 
end 

Und jetzt hat show.html.erb ein neu regenerierten @new_reply Objekt auf Fehler zu überprüfen.

Da ist etwas offensichtlich falsch - Sie sollten nicht ganze Objekte innerhalb der Sitzung speichern. Aber da das Reply-Objekt, das wir in RepliesController # create speichern wollten, nie gespeichert wurde, wie behalte ich es zwischen Controller-Aktionsaufrufen?

Oder wenn es eine größere Design-Lösung gibt, zögern Sie nicht, es zu teilen. Das ist so hässlich, dass es mir weh tut. Vielen Dank.

Antwort

2

Wie wäre es statt Umleiten, statt render :action => "discussions/show" statt. Ich würde sagen, Sie müssten die @discussion Variable auch einrichten, aber dies sollte getan werden, da die Antworten verschachtelte Ressourcen innerhalb der Diskussionen sind, richtig?

+0

Ich mache diese Art von Dingen so. Stellen Sie sicher, dass Sie @discussion und @reply geladen haben. – klew

+0

Ich dachte daran, aber es gibt zwei Gründe, warum ich den Render-Ansatz nicht mag: 1. Es ändert die URL; Ich möchte die Illusion behalten, dass du immer noch auf derselben Seite bist (weil du es bist). 2. Ich mag wirklich nicht die Tatsache, dass ich die Logik in DiscussionsController # show kopieren müsste - stelle sicher, dass die gleichen Filter angewendet werden, und stelle sicher, dass @discussion und andere Instanzvariablen auf dieselbe Weise ausgewählt werden (benutzerdefinierte Funde) mit Bedingungen, etc.) - scheint nicht sehr trocken. – Raphomet

2

Statt der Sitzung würde ich die Antwort in der flash speichern, die für das Übergeben von Nachrichten/Objekten über eine Aktion gut ist.

Der Controller würde die Antwort im Flash einfach speichern, wenn es nicht gültig und Umleitung ist:

ein bisschen klüger und sein müßte
if @reply.save 
    ... 
else 
    flash[:reply] = @reply 
end 

Und Ihre Form Logik auf der Diskussionen/show Seite greifen Antwort im Flash oder die neue (die ich nehme an, Sie sind in der Diskussion/show-Aktion erstellen):

form_for(flash[:reply] || @reply) do 
    ... 
end 
+0

Ich war abgeneigt, dies zu verwenden - Obie Fernandez, Autor von The Rails Way, sagt Flash für Nachrichten und die Sitzung zu verwenden, um Werte zwischen Aktionen zu übergeben. Aber die Rails-Dokumentation (http://api.rubyonrails.org/classes/ActionController/Flash.html) scheint zu implizieren, dass der Flash ein geeigneter Ort ist, um jede Art von Objekt vorübergehend zu speichern. Ich denke, ich werde das jetzt versuchen und daraus lernen, wenn es zurückkommt, um mich zu verbrennen. :) – Raphomet

0

ich würde sagen, dass die Art und Weise Sie es tun sinnvoll ist. Nicht das sauberste, aber es ist RESTful.

Der Vorschlag von Radar ist groß, aber in der aktuellen Version von Rails, render :action => "discussions/show" erstellt nicht das richtige Verhalten, zumindest in meinen Versuchen, die ohne verschachtelte Ressourcen Routing waren. Die Verwendung von render :controller => "discussions", :action => "show" ergibt ein anderes Verhalten, das nicht das ist, wonach das Poster sucht.

Verwandte Themen