Rails: просмотр представления с внешнего контроллера

Я пытаюсь создать строку HTML, используя представление. Я хотел бы сделать это из класса, который не является контроллером. Как я могу использовать движок рендеринга рельсов вне контроллера? Как работает ActionMailer?

Спасибо!

Ответ 1

Rails 5 теперь поддерживает это гораздо более удобным способом, который обрабатывает создание запроса и еще что-то за кулисами:

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

Это отображает app/views/users/show.html.erb и устанавливает переменную экземпляра @user, поэтому вам не нужно вносить какие-либо изменения в ваш шаблон. Он автоматически использует макет, указанный в ApplicationController (application.html.erb по умолчанию).

Тест показывает несколько дополнительных опций и подходов.

Ответ 2

Вы можете использовать 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

Ответ 3

Нет необходимости перекручивать приложение со слишком большим количеством драгоценных камней. Поскольку мы знаем, что 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 - это строка, которая должна быть сохранена или отправлена ​​в любом месте.

Ответ 4

Технически, ActionMailer является подклассовой реализацией AbstractController::Base. Если вы хотите реализовать эту функцию самостоятельно, вы, скорее всего, захотите наследовать и от AbstractController::Base.

Здесь есть хороший блог: https://www.amberbit.com/blog/2011/12/27/render-views-and-partials-outside-controllers-in-rails-3/, который объясняет необходимые шаги.

Ответ 5

Вызов метода прямого отображения на 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 }
)

Ответ 6

"Я пытаюсь создать строку 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

Ответ 8

Лучше всего визуализировать представление с помощью контроллера, для чего они предназначены, а затем преобразовать его в строку, поскольку это ваша конечная цель.

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