webentwicklung-frage-antwort-db.com.de

Schienen: Render-Ansicht von außerhalb des Controllers

Ich versuche, eine HTML-Zeichenfolge mithilfe einer Ansicht zu erstellen. Ich möchte dies aus einer Klasse rendern, die kein Controller ist. Wie kann ich die Rails-Rendering-Engine außerhalb eines Controllers verwenden? Ähnlich wie ActionMailer?

Vielen Dank!

19
prajo

Rails 5 unterstützt dies nun auf viel bequemere Weise, indem es das Anlegen einer Anfrage und was nicht hinter den Kulissen erledigt:

rendered_string = ApplicationController.render(
  template: 'users/show',
  assigns: { user: @user }
)

Dadurch wird app/views/users/show.html.erb gerendert und die Instanzvariable @user festgelegt, sodass Sie keine Änderungen an Ihrer Vorlage vornehmen müssen. Es verwendet automatisch das in ApplicationController angegebene Layout (standardmäßig application.html.erb). 

Der Test zeigt eine Handvoll zusätzlicher Optionen und Ansätze.

36
coreyward

Sie können ActionView :: Base verwenden, um dies zu erreichen.

view = ActionView::Base.new(ActionController::Base.view_paths, {})
view.render(file: 'template.html.erb')

Die ActionView :: Base initialize benötigt:

  1. Ein Kontext, der die Suchpfade der Vorlage darstellt
  2. Ein assigns-Hash, der die Variablen für die Vorlage bereitstellt

Wenn Sie Helfer einschließen möchten, können Sie diese mit class_eval einschließen:

view.class_eval do
  include ApplicationHelper
  # any other custom helpers can be included here
end
31
cweston

Sie müssen Ihre App nicht mit zu vielen Edelsteinen aufblähen. Wie wir wissen, ist ERB bereits in Ihrer Rails-App enthalten.

@jdf = JDF.new
@job = ERB.new(File.read(Rails.root + "app/views/entries/job.xml.erb"))
result =  @job.result(binding)

Oben ist ein Codeausschnitt einer App, an der ich gerade arbeite. 

  • @jdf ist ein Objekt, das in der Sicht erb ausgewertet werden soll. 
  • In meinem Fall musste ich xml rendern.
  • result ist eine Zeichenfolge, die gespeichert oder an einen beliebigen Ort gesendet werden kann.
4
Jesse

Das Aufrufen der direkt auf ApplicationController gerenderten Methode kann einen Fehler auslösen

 Helper Devise: could not find the `Warden::Proxy` instance on request environment

Stattdessen können wir ApplicationController.renderer.render wie verwenden

 rendered_string = ApplicationController.renderer.render(
     partial: 'users/show',
     locals: { user: user }
)
1
Syed Shibli

Technisch gesehen ist ActionMailer eine Unterklassenimplementierung von AbstractController::Base. Wenn Sie diese Funktionalität selbst implementieren möchten, möchten Sie wahrscheinlich auch von AbstractController::Base erben.

Es gibt einen guten Blog-Beitrag hier: https://www.amberbit.com/blog/2011/12/27/render-views-and-partials-outside-controllers-in-Rails-3/ das erklärt die erforderlichen Schritte.

1
locriani

"Ich versuche, eine HTML-Zeichenfolge mithilfe einer Ansicht zu erstellen." - Wenn Sie damit meinen, dass Sie sich im Kontext einer Ansichtsvorlage befinden, verwenden Sie einfach eine Hilfsmethode oder rendern Sie eine teilweise.

Wenn Sie sich in einem anderen "Plain Old Ruby Object" befinden, können Sie das ERB-Modul direkt verwenden:

erb = ERB.new("path/to/template")
result = erb.result(binding)

Der Trick besteht darin, das 'bindende' Objekt zu erhalten, das den Kontext für den Code in der Vorlage angibt. ActionController und andere Rails-Klassen stellen es kostenlos zur Verfügung, aber ich konnte keine Referenz finden, aus der hervorgeht, woher es kommt.

http://www.Ruby-doc.org/stdlib-2.2.0/libdoc/erb/rdoc/ERB.html#method-i-result

0
vpsz

Als Nachschlagewerk fand ich Diesen praktischen Edelstein, der dies zu einem Kinderspiel macht:

https://github.com/yappbox/render_anywhere

0
prajo

Am besten rendern Sie die Ansicht mit einem Controller, da sie dafür sind, und dann konvertieren Sie sie in eine Zeichenfolge, da dies Ihr Endziel ist.

require 'open-uri'
html = open(url, &:read)
0
steven_noble