使用Prawn和Carrierwave上载PDF而不将文件保存在磁盘上

时间:2019-01-04 16:06:16

标签: ruby-on-rails prawn

我在后台作业中为发票生成PDF文件,并且希望将其附加到发票上。我使用Carrierwave进行文件上传,但是在这里我不从UI上传文件。我希望能够附加文件而不将其保存在磁盘上。

invoice.rb

mount_uploader :file, InvoiceFileUploader

后台工作

class GeneratePdfJob < ApplicationJob
  queue_as :default

  def perform(invoice)
    pdf = InvoiceServices::PdfGenerator.new(invoice)
    file_name = [invoice.number.gsub('/','-'), invoice.due_date.to_s, SecureRandom.urlsafe_base64].join('-') + '.pdf'
    pdf.render_file(file_name)
    file = File.new(file_name)
    invoice.file = file
    File.delete(file_name)
  end
end

因此,现在我调用render_file方法来实际创建文件,但是此文件保存在应用程序的根文件夹中,因此以后需要删除它。有没有更好的办法?有没有办法在不实际将文件保存到磁盘的情况下附加文件?

1 个答案:

答案 0 :(得分:1)

您要归档的内容确实令人印象深刻。谢谢你的主意。这将减少PDF生成过程中与磁盘IO相关的许多问题。

第一名:Renders the PDF document to a string

使用Prawn::Document#render方法代替render_file方法,该方法返回PDF的字符串表示形式。

第二个:use that string to upload to carrier wave without any tempory file

# define class that extends IO with methods that are required by carrierwave
class CarrierStringIO < StringIO
  def original_filename
    "invoice.pdf"
  end

  def content_type
    "application/pdf"
  end
end

class InvoiceFileUploader < CarrierWave::Uploader::Base
  def filename
    [model.number.gsub('/','-'), model.due_date.to_s, SecureRandom.urlsafe_base64].join('-') + '.pdf'
  end
end

class Invoice
  mount_uploader :file, InvoiceFileUploader

  def pdf_data=(data)
    self.file = CarrierStringIO.new(data)
  end
end

class GeneratePdfJob < ApplicationJob
  queue_as :default

  def perform(invoice)
    pdf = InvoiceServices::PdfGenerator.new(invoice)        
    invoice.pdf_data = pdf.render
  end
end