How to render rails's template as PDF and ensure that it is PDF with FileMagic?

223 Views Asked by At

The Issue: App has a network of various printers. Some of them work through PrintNode. They should receive string encoded as base64. Code which receives my document looks like

PrintNode::PrintJob.new printer_id, 'PrinterClass', method, Base64.encode64(document), 'AppName'

method should contain method - in my case raw_base64 or pdf_base64. So I have next code

case FileMagic.mime.buffer(document, true)
when 'text/plain'
  then method = 'raw_base64'
# when 'text/html' # this commented because I have to avoid it
#   then method = 'pdf_base64'
when 'application/pdf'
  then method = 'pdf_base64'
else
  raise InvalidDocumentError
end

I render the document with Controller.render method

document = InstanceController.render :label, { id: instance.id, formats: :pdf, locals: { instance: instance_note } }

As I see document is a string(which includes html) and because of that FileMagic.mime returns text/html(I think so). This is a problem. I'm not near printers and can't just test with a real printer. Also, we have 5 printer types(barcodes, a4, etc.). So I'm not sure that I can just use commented approach(text/html).

So the main question - can I render real PDF with Controller.render method? (if yes then how?)

NOTE: We use PrinceXML and gem princely. So when the same controller used to return PDF through a browser then I get valid good PDF.

1

There are 1 best solutions below

0
On

Ok. It is a problem with princely. It rewrites an instance method render, not a class method. So to generate PDF with princely I have to call InstanceController.new.render. But its signature is not the same, so it is not very useful.

  1. InstanceController.new.render would call princely only if first param is a hash but in this case we cant send action name.
  2. Because of first item princely tries to get action name fron controller's action_name which in our case is nil and crashes.

But at the same time, I found the way to generate pdf with princely from html explicitly

princely = Princely::Pdf.new
document = princely.pdf_from_string(InstanceController.render action_name, options) # it generates valid PDF from html