TL;DR
ac = ApplicationController.new
ac.instance_variable_set(:@user, User.find(42)) # インスタンス変数をインジェクション
ac.render_to_string 'users/show', # レンダリングしたいテンプレート
layout: false, # `layout: false`がないとエラー
locals: { params: {} } # ローカル変数が使われる際、セットが必要
=> "<!DOCTYPE html>\n<html lang='ja'>\n<head>\n<meta charset='UTF-8'>\n<title>User ID: 42</title>\n</meta>\n</head>\n<body>\n<h1>User Name: Foo</h1>\n</body>\n</html>\n"
本文
去年はとある問題を解決するために、「Rails Consoleなど任意の場所で任意のViewを任意条件でRenderする」 を作成しました。
今年は別件の調査で、wicked_pdfのサンプルコードにて下記の構文を見つかりました。
pdf_html = ActionController::Base.new.render_to_string(template: 'controller_name/action_name', layout: 'pdf')
pdf = WickedPdf.new.pdf_from_string(pdf_html)
この構文は実際に使えるであれば、去年みたいにinlineでコントローラーを作成せずに、もっと手軽にViewをレンダリングできるはずです。
しかしながら、実際使って見ると、ActionController::Base
を使う場合Helperが実行されない問題が見つかりました。
ac.extend(ApplicationHelper)
で救済措置を取ってもViewの中では使えませんでした。
幸い海外の記事を漁っている間、ApplicationController
のインスタンスなら、Helperが使えるとわかりました。
そしてインスタンス変数を利用したい場合は、ネット上でlocals: { @user => User.first }
のような書き方がありましたが、実際テストしてみたら使えませんでした。
instance_variable_set(:@user, User.first)
を使えば、無事にインスタンス変数をインジェクションできました。