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!
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.
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:
assigns
-Hash, der die Variablen für die Vorlage bereitstelltWenn 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
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. xml
rendern.result
ist eine Zeichenfolge, die gespeichert oder an einen beliebigen Ort gesendet werden kann.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 }
)
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.
"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
Als Nachschlagewerk fand ich Diesen praktischen Edelstein, der dies zu einem Kinderspiel macht:
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)