Rails 5在本地渲染中设置实例变量

Dee*_*kor 2 ruby-on-rails wicked-pdf ruby-on-rails-5

我有一些复杂的PDF生成逻辑,需要在控制器外部渲染视图,然后将HTML传递到WickedPDF:

ActionView::Base.send(:define_method, :protect_against_forgery?) { false }
av = ActionView::Base.new
av.view_paths = ActionController::Base.view_paths

income_statement_html = av.render :template => "reports/income_statement.pdf.erb", :layout => 'layouts/report.html.erb',
                                  locals: {:@revenue_accounts => revenue_accounts,
                                           :@expense_accounts => expense_accounts,
                                           :@start_date => start_date,
                                           :@end_date => end_date,
                                           :@business => business}
Run Code Online (Sandbox Code Playgroud)

这一切都适用于Rails 4,但在我们升级到Rails 5时已停止工作.

我们在这里设置的所有实例变量最终都nil在视图中.还有一种方法可以像这样从渲染调用中设置实例变量吗?

cor*_*ard 5

引入了Rails 5 ActionController::Base.render,它允许你这样做:

rendered_html = ApplicationController.render(
  template: 'reports/income_statement',
  layout: 'report',
  assigns: {
    revenue_accounts: revenue_accounts,
    expense_accounts: expense_accounts,
    start_date: start_date,
    end_date: end_date,
    business: business
  }
)
Run Code Online (Sandbox Code Playgroud)

然后您可以将其传递给WickedPDF:

WickedPdf.new.pdf_from_string(rendered_html)
Run Code Online (Sandbox Code Playgroud)

您可以阅读有关.renderWickedPDF的更多信息并将其与WickedPDF一起使用,以及如何在此博客文章中将此功能提取到可重用对象中的示例.


Dee*_*kor 2

ActionView::Base有一个方法allocate可以调用它来设置实例变量。

    av.assign({revenue_accounts: revenue_accounts,
           expense_accounts: expense_accounts,
           start_date: start_date,
           end_date:  end_date,
           business: business})

income_statement_html = av.render :template => "reports/income_statement.pdf.erb", :layout => 'layouts/report.html.erb'
Run Code Online (Sandbox Code Playgroud)