Ruby on Rails - Büroklammer und dynamische Parameter

8

Ich schreibe einen Bildupload-Code für Ruby on Rails mit Paperclip, und ich habe eine funktionierende Lösung, aber es ist sehr hacky, also würde ich wirklich Ratschläge dafür, wie man es besser implementieren kann, schätzen. Ich habe eine "Asset" -Klasse, die Informationen über die hochgeladenen Bilder enthält, einschließlich des Paperclip-Anhangs, und eine "Generator" -Klasse, die Größeninformationen einkapselt. Jedes "Projekt" verfügt über mehrere Assets und Generatoren; Alle Assets müssen in der Größe angepasst werden, die von jedem Generator angegeben wird. Jedes Projekt hat daher eine bestimmte Größe, die alle seine Vermögenswerte haben sollten.

Generatormodell:

%Vor%

Anlagenmodell:

%Vor%

Asset Controller erstellen Methode:

%Vor%

Das Problem, das ich habe, ist ein Hühnerei-Problem: Das neu erstellte Asset weiß nicht, welche Generatoren (Größenspezifikationen) verwendet werden sollen, bis es ordnungsgemäß instanziiert wurde. Ich habe versucht, @ project.assets.build, aber dann der Paperclip-Code wird noch ausgeführt, bevor das Asset seine Projekt Zuordnung gesetzt und Nils auf mich.

Der 'if @generators == nil' Hack ist so, dass die Update-Methode ohne weiteres Hacken im Controller funktioniert.

Alles in allem fühlt es sich ziemlich schlecht an. Kann jemand vorschlagen, wie man dies auf eine vernünftigere Weise schreibt, oder sogar eine Annäherung, um für diese Art von Sache zu nehmen?

Vielen Dank im Voraus! :)

    
Dave 13.01.2013, 15:40
quelle

3 Antworten

15

Bei einem Projekt, bei dem versucht wurde, dynamische Stile zu verwenden, die auf dem zugehörigen Modell mit einer polymorphen Beziehung basieren, stieß ich auf das Problem mit dem Papierclip Huhn / Ei. Ich habe meine Lösung an Ihren bestehenden Code angepasst. Eine Erklärung folgt:

%Vor%

Um zu vermeiden, dass Paperclip versucht, die dynamischen Stile abzurufen, bevor die Projektbeziehungsinformationen weitergegeben wurden, können Sie alle image -Attribute einem Nicht-Paperclip-Attribut zuweisen (in diesem Fall habe ich Benenne es deferred_image ). Der after_save Hook weist den Wert von @deferred_image auf self.image zu, was den ganzen Paperclip jazz auslöst.

Ihr Controller wird zu:

%Vor%

Und die Aussicht:

%Vor%

Diese Lösung ermöglicht auch die Verwendung von accepts_nested_attributes für die assets -Verbindung im Project -Modell (das ist derzeit die Art, wie ich es verwende - um Assets als Teil der Erstellung / Bearbeitung eines Projekts hochzuladen).

>

Es gibt einige Nachteile dieses Ansatzes (zB die Büroklammer image in Bezug auf die Gültigkeit der Asset Instanz zu validieren wird schwierig), aber es ist das Beste, was ich mir vorstellen kann verschiebt die Ausführung der style -Methode, bis die Verbindungsinformationen ausgefüllt wurden.

Ich werde diese Frage im Auge behalten, um zu sehen, ob jemand eine bessere Lösung für dieses Problem hat!

Wenn Sie zumindest die gleiche Lösung verwenden, können Sie die folgende Methode zur Verbesserung Ihrer Asset#styles -Methode anwenden:

%Vor%

Ist genau dasselbe wie Ihre bestehende Methode, aber kürzer.

    
Cade 26.01.2013, 17:43
quelle
5

Obwohl ich Cades Lösung wirklich mag, nur ein Vorschlag. Es scheint, als ob die "Stile" zu einem Projekt gehören ... also warum berechnen Sie die Generatoren nicht dort?

Zum Beispiel:

%Vor%

EDIT: Versuchen Sie, Ihren Controller zu ändern (vorausgesetzt, das Projekt hat viele Assets):

%Vor%     
Joe Pym 30.01.2013 20:43
quelle
2

Ich habe gerade ein ähnliches Problem gelöst, das ich hatte. In meinem "styles" lambda gebe ich einen anderen Stil zurück, abhängig vom Wert eines "category" -Attributs. Das Problem ist jedoch, dass Image.new (attrs) und image.update_attributes (attrs) die Attribute nicht in einer vorhersagbaren Reihenfolge festlegen, und daher kann ich nicht garantieren, dass image.category vor meinen Styles Lambda einen Wert hat wird genannt. Meine Lösung bestand darin, attributes = () in meinem Image-Modell wie folgt zu überschreiben:

%Vor%

Damit wird sichergestellt, dass das Büroklammerattribut nach den anderen Attributen gesetzt ist und sie somit in einem: style lambda verwenden kann.

In Situationen, in denen das Büroklammerattribut "manuell" eingestellt ist, wird es eindeutig nicht helfen. Unter diesen Umständen können Sie sich jedoch selbst helfen, indem Sie eine sinnvolle Reihenfolge festlegen. In meinem Fall könnte ich schreiben:

%Vor%

(Büroklammer 2.7.4, Schienen 3, Rubin 1.8.7)

    
kierantop 05.02.2013 16:23
quelle

Tags und Links