Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 5 render set instance variables in locals

I have some complicated PDF generation logic that requires rendering a view outside of a controller and then passing the HTML into 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}

This all works fine on Rails 4 but has stopped working when we upgraded to Rails 5.

All the instance variables we are setting here end up as nil inside the view. Is there still a way to set instance variables from the render call like this?

like image 738
Deekor Avatar asked Dec 24 '22 21:12

Deekor


1 Answers

Rails 5 introduced ActionController::Base.render, which allows you to do this instead:

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
  }
)

Which you can then pass to WickedPDF:

WickedPdf.new.pdf_from_string(rendered_html)

You can read more about .render and using it with WickedPDF, as well get some examples of how to extract this functionality into reusable objects on this blog post.

like image 147
coreyward Avatar answered Jan 09 '23 20:01

coreyward