How to generate a PDF using wicked_pdf from an API
Asked Answered
C

1

5

Im creating an API that should generate a PDF based on some information on the database.

When trying to call the action im getting an error:

ActionController::UnknownFormat (ActionController::UnknownFormat):
app/controllers/v1/trips_controller.rb:56:in `print_monthly_trips'

This is my controllers:

/#application_controller.rb
class ApplicationController < ActionController::API
  include Response
  include ExceptionHandler
  include Pundit
  include ActionController::MimeResponds

 /#trips_controler.rb
def print_monthly_trips

  @trips_to_print = current_user.trips_for_month(3)

  respond_to do |format|
    format.html
    format.pdf do
      render pdf: "file_name",
      template: "trips/report.html.erb",
      layout: 'pdf.html'
    end
    format.json do
      render pdf: "file_name",
      template: "trips/report.html.erb",
      layout: 'pdf.html'
    end
  end
end

My routes:

get 'print_monthly_trips', to: 'trips#print_monthly_trips'

Im calling my API with:

http GET https://localhost/print_monthly_trips Accept:'application/vnd.trips.v1+json' Authorization:'my_token'

So, why im getting this:

ActionController::UnknownFormat (ActionController::UnknownFormat):

app/controllers/v1/trips_controller.rb:56:in `print_monthly_trips'

Crosspiece answered 18/2, 2019 at 19:56 Comment(5)
what line is line 56?Yancy
respond_to do |format|Crosspiece
rails version? Is the pdf data type registered in Mime::Type? Why are you requesting json and returning a PDF? Your layout looks wrong according to the docsAfterword
Its just a test. My Mime types are like this: Mime::Type.register "application/pdf", :pdfCrosspiece
Even if I only put this: respond_to do |format| format.xml { render(xml: "fdsfds") } format.json { render(json: "fdsfdsfd" ) } end It breaks the same wayCrosspiece
C
9

Rails controllers that inherit from ActionController::API don't have the ability to render views or use view helpers, which is necessary for many WickedPdf use-cases.

You can either move the PDF creating action to another non-API Rails controller that inherits from ActionController::Base instead, or instantiate one in your action like this:

def print_monthly_trips
  pdf_html = ActionController::Base.new.render_to_string(template: 'trips/report.html.erb', layout: 'pdf.html')
  pdf = WickedPdf.new.pdf_from_string(pdf_html)
  send_data pdf, filename: 'file_name.pdf'
end

If you don't want to incur the overhead to instantiate ActionController::Base just to generate a PDF, you may need to make some adjustments to your template, and build the HTML directly with ERB or Erubis something like this:

def print_monthly_trips
  layout = Erubis::Eruby.new(File.read(Rails.root.join('app/views/layouts/pdf.html.erb')))
  body = Erubis::Eruby.new(File.read(Rails.root.join('app/views/trips/report.html.erb')))
  body_html = body.result(binding)
  pdf_html = layout.result(body: body_html) # replace `yield` in layout with `body`
  pdf = WickedPdf.new.pdf_from_string(pdf_html)
  send_data pdf, filename: 'file_name.pdf'
end

But be aware you won't have access to view helpers, and most wicked_pdf_asset helpers this way.

Crusted answered 19/2, 2019 at 23:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.