2009-01-23 8 views
24

Ich habe zwei Controller für zwei jeweilige Modelle, zum Beispiel Fotos und Kategorien. Index- und Show-Methoden sind in jedem Controller sehr ähnlich und die Ansichten sind identisch. Was ist die beste Methode, um die Ansicht der beiden Modelle zu teilen?Zwei Controller für eine gemeinsame Ansicht in Ruby on Rails

Ich habe allerdings zwei Möglichkeiten:

  • einen Helfer verwenden. In der Helfer wird der Code für die Ansicht, und ruft den Helfer aus jeder Ansicht (Fotos/Ansichten und Kategorien/Ansichten)

  • Verwenden Sie eine teilweise in jeder Ansichten. Ich denke, es ist eine sauberere Lösung, aber ich sehe riesige DRYs in meinen Gedanken, wenn ich diese Lösung programmieren werde.

So habe ich zwei Controller von zwei Modellen, die jeweils an und lege ein @photo Objekt (Fotos Controller mit allen Fotos und Kategorien Controller nur mit den Fotos der ausgewählten Kategorie) und ich brauche einen Blick auf zeige beides.

Ich suche eine elegante Lösung für diese, beschweren REST und DRY principes. Irgendeine Idee?

Vielen Dank im Voraus.

Antwort

38

Ich habe eine ähnliche Situation mit einem meiner Projekte. Alle Löschansichten für die meisten Controller werden auf die gleiche Weise formatiert, zeigen die gleichen Bestätigungsfelder an und stellen einfach eine vorhersagbare Anzeige des Objekts dar, das gerade gelöscht wird.

Die Lösung war meiner Meinung nach ziemlich einfach und elegant. Einfach ausgedrückt, was wir (die Entwickler) gemacht haben, war ein neues Verzeichnis in app/views namens shared zu erstellen und geteilte Ansichten dort zu setzen. Dies können vollständige Vorlagendateien oder nur Teiltöne sein.

Ich würde vorschlagen, eine gemeinsame Vorlage (in keiner Kategorie oder Foto-Ansicht Verzeichnisse, sondern im freigegebenen Verzeichnis) und Rendering manuell aus der Ansicht.

z.B. haben ein Verfahren als solche in beiden Controllern und eine Datei app/views/shared/photo.html.erb:

def show 
    @photo = Photo.first # ... or whatever here 
    render :template => 'shared/photo' 
end 

Diese die gemeinsame Vorlage erfolgreich machen sollte. Es ist die DRYest-Route und hat nicht das Gefühl der Umweltverschmutzung, die man bekommt, wenn man eine mehr oder weniger leere Ansicht in jedem View-Verzeichnis eines Controllers verwendet, nur um einen geteilten Partial aufzunehmen, wie ich deine Frage vermute.

+0

Ah brilliant! Ich habe gerade 2 Stunden damit verbracht, einen meiner Partials auszutrocknen, der mir Kummer bereitet hat. Danke - das ist so einfach. – brad

+0

Was passiert jetzt, wenn Sie diese Vorlage mit AJAX laden müssen? :) – Noz

+0

Wenn ich dies in Rails 4.2.5 versuche, erhalte ich den Fehler "ActionController :: RackDelegation # content_type an @ _response.content_type delegiert, aber @_response ist nil: #

1

Ich würde einen Helfer verwenden, weil sie unter Ansichten geteilt werden. Für den HTML-Teil würde ich Partials verwenden, also wäre es eine Mischung aus beiden Möglichkeiten.

+0

Ja, ich denke, es ist die beste Lösung aufgrund seiner Sichtbarkeit von jedem Controller oder View, aber ist es richtig, View-Code (HTML-Code) in einem Helfer zu setzen? – ARemesal

+0

Es wäre besser, den Code nicht in die Helfer zu schreiben, es sei denn, es sind weniger als ein paar Zeilen. –

+0

Ich würde eine Mischung aus partiellen für den HTML-Code und Helfer für den Code verwenden. – Keltia

6

über die first Antwort:

Wenn die teilweise aus einer Ansicht gerendert werden muß:

 
<%= render :partial => "shared/photo" %> 

und die teilweise in app/views sein muss/shared/_photo.html.erb

1

Das sieht nach einem guten Anwendungsfall für den Edelstein Cells aus.

0

@bjeanes Wenn alle Ihre gelöschten Ansichten identisch sind, können Sie views/default/delete.html erstellen.Erb und alle Löschaktionen werden es verwenden.

Das ist, was ich tue: Die meisten meiner Ansichten auf Standard sind, und ich schaffe nur bestimmte diejenigen wenn

-Update benötigt: Ok, dieser Beitrag ist aus dem Jahr 2009, wie auch immer, ich werde mein Kommentar hier halten in Falls jemand wie ich von Google hierher kommt.