Search code examples
ruby-on-railssidekiqpartialswicked-pdf

Wicked PDF generation from Sidekiq worker: How to pass a partial?


I'm need to print PDFs using the WickedPDF gem and Sidekiq. I think/hope it is almost working, here is the relevant controller code:

def print_token
  @token = Token.find(params[:id])
  TokenPdfPrinter.perform_async(@token.id)
  redirect_to :back
end

And the Worker:

class TokenPdfPrinter
  include Sidekiq::Worker
  sidekiq_options retry: false

  def perform(token_id)
    @token = Token.find(token_id)
    # create an instance of ActionView, so we can use the render method outside of a controller
    av = ActionView::Base.new()
    av.view_paths = ActionController::Base.view_paths

    # need these in case your view constructs any links or references any helper methods.
    av.class_eval do
      include Rails.application.routes.url_helpers
      include ApplicationHelper
    end

    pdf = av.render pdf: "Token ##{ @token.id }",
               file: "#{ Rails.root }/app/admin/pdfs/token_pdf.html.erb",
             layout: 'layouts/codes',
        page_height: '3.5in',
         page_width: '2in',
             margin: {  top: 2,
                         bottom: 2,
                           left: 3,
                          right: 3 },
            disposition: 'attachment',
     disable_javascript: true,
         enable_plugins: false,
        locals: { token: @token }

    send_data(pdf, filename: "test.pdf",  type: "application/pdf")
  end
end

And the partials getting rendered:

<!DOCTYPE html>
<html>
    <head>
      <title>WuDii</title>    
      <meta http-equiv="content-type" content="text/html; charset=utf-8" />
      <%= wicked_pdf_stylesheet_link_tag    "application" %>
      <%= wicked_pdf_stylesheet_link_tag    "codes" %>
      <%= wicked_pdf_javascript_include_tag "application" %>
    </head>
    <body>
        <%= yield %>
    </body>
  </html>

And token_pdf.html.erb:

<% @token = @token %>
<br>
<div class="barcode text-center"><br><br><br><br><br><br><br><br>
  <p><%= @token.encrypted_token_code.scan(/.{4}|.+/).join('-') %></p>
  <h3><strong>(<%= number_with_delimiter(@token.credits, delimiter: ',') %>)</strong></h3>
</div>

And I'm getting an error that @token is nil in token_pdf.html.erb. Any suggestions what I'm doing wrong here?


Solution

  • You pass local variable token to view, so you should reference it without @. Change first line to <% @token = token %> and it should work. Or just skip first line and reference token by local variable.