Я пытаюсь создать строку HTML, используя представление. Я хотел бы сделать это из класса, который не является контроллером. Как я могу использовать движок рендеринга рельсов вне контроллера? Как работает ActionMailer?
Спасибо!
Я пытаюсь создать строку HTML, используя представление. Я хотел бы сделать это из класса, который не является контроллером. Как я могу использовать движок рендеринга рельсов вне контроллера? Как работает ActionMailer?
Спасибо!
Rails 5 теперь поддерживает это гораздо более удобным способом, который обрабатывает создание запроса и еще что-то за кулисами:
rendered_string = ApplicationController.render(
template: 'users/show',
assigns: { user: @user }
)
Это отображает app/views/users/show.html.erb
и устанавливает переменную экземпляра @user
, поэтому вам не нужно вносить какие-либо изменения в ваш шаблон. Он автоматически использует макет, указанный в ApplicationController
(application.html.erb
по умолчанию).
Вы можете использовать ActionView:: Base, чтобы достичь этого.
view = ActionView::Base.new(ActionController::Base.view_paths, {})
view.render(file: 'template.html.erb')
ActionView:: Base инициализирует:
assigns
, предоставляющий переменные для шаблонаЕсли вы хотите включить помощников, вы можете использовать class_eval для их включения:
view.class_eval do
include ApplicationHelper
# any other custom helpers can be included here
end
Нет необходимости перекручивать приложение со слишком большим количеством драгоценных камней. Поскольку мы знаем, что ERB уже включен в ваше приложение Rails.
@jdf = JDF.new
@job = ERB.new(File.read(Rails.root + "app/views/entries/job.xml.erb"))
result = @job.result(binding)
Выше приведен фрагмент кода приложения, над которым я работаю.
@jdf
- объект, который будет оцениваться в представлении erb
.xml
.result
- это строка, которая должна быть сохранена или отправлена в любом месте.Технически, ActionMailer
является подклассовой реализацией AbstractController::Base
. Если вы хотите реализовать эту функцию самостоятельно, вы, скорее всего, захотите наследовать и от AbstractController::Base
.
Здесь есть хороший блог: https://www.amberbit.com/blog/2011/12/27/render-views-and-partials-outside-controllers-in-rails-3/, который объясняет необходимые шаги.
Вызов метода прямого отображения на ApplicationController может вызвать ошибку
Helper Devise: could not find the 'Warden::Proxy' instance on request environment
Вместо этого мы можем использовать ApplicationController.renderer.render как
rendered_string = ApplicationController.renderer.render(
partial: 'users/show',
locals: { user: user }
)
"Я пытаюсь создать строку HTML, используя представление". - Если вы имеете в виду, что вы находитесь в контексте шаблона представления, просто используйте вспомогательный метод или сделайте частичный.
Если вы находитесь в другом "обычном старом Ruby Object", тогда имейте в виду, что вы можете напрямую использовать модуль ERB:
erb = ERB.new("path/to/template")
result = erb.result(binding)
Трюк получает объект привязки, который дает контекст для кода в шаблоне. ActionController и другие классы Rails открывают его бесплатно, но я не смог найти ссылку, объясняющую, откуда она взялась.
http://www.ruby-doc.org/stdlib-2.2.0/libdoc/erb/rdoc/ERB.html#method-i-result
В будущем, я нашел этот удобный камень, который делает это легким:
Лучше всего визуализировать представление с помощью контроллера, для чего они предназначены, а затем преобразовать его в строку, поскольку это ваша конечная цель.
require 'open-uri'
html = open(url, &:read)