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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With