Загрузка PDF с Prawn и Carrierwave без сохранения файла на диске - PullRequest
0 голосов
/ 04 января 2019

Я создаю файл PDF для накладной в фоновом задании и хочу прикрепить его к накладной. Я использую Carrierwave для загрузки файлов, но здесь я не загружаю его из пользовательского интерфейса. Я хотел бы иметь возможность прикрепить файл, не сохраняя его на диске.

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 голосов
/ 26 января 2019

то, что вы пытаетесь заархивировать, действительно впечатляет. Спасибо за идею. это уменьшит множество проблем с дисковым вводом-выводом при генерации PDF.

1-й: Отображает документ PDF в строку

вместо метода render_file используйте метод Prawn::Document#render, который возвращает строковое представление PDF.

2nd: использовать эту строку для загрузки на несущую волну без какого-либо временного файла .

# 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
...