Сгенерированный WickedPDF файл PDF при загрузке с помощью святыни не заполняет поле данных

Я перехожу с Paperclip на весь мой процесс загрузки, и у меня возникла проблема с сгенерированным PDF-файлом.

Дочерняя модель, которая обрабатывает загрузку, представляет собой полиморфную модель с именем quotepdf.

В какой-то момент создается quotepdf экземпляр, к которому привязано вложение.

Вот модель quotepdf, адаптированная для святыни

class Quotepdf < ApplicationRecord
  include QuotesAndInvoicesUploader::Attachment.new(:quote)    
  belongs_to :quotable, polymorphic: true

end

загрузчик:

class QuotesAndInvoicesUploader < Shrine
    plugin :validation_helpers # to validate pdf
    plugin :delete_raw

    Attacher.validate do
        validate_max_size 1.megabyte
        validate_mime_type_inclusion ['application/pdf']
    end

    def generate_location(io, context)
        type  = context[:record].class.name.downcase if context[:record]
           name  = super

        [type, name].compact.join("/")
      end

end

и работник Sidekiq, который обрабатывает создание «записи quotepdf» и вложения PDF с помощью Wickedpdf:

class PhotographerQuotePdfWorker
  include Sidekiq::Worker
  sidekiq_options retry: false

  def perform(id)
    @quote = Photographerquote.find(id)
    ac = ActionController::Base.new()
    pdf_string = ac.render_to_string pdf: 'photographerquote-'[email protected]_id.to_s, template: "photographerquote/print_quote.pdf.erb", encoding: "UTF-8", locals: {pdfquote: @quote}

    new_pdf = @quote.build_quotepdf
    new_pdf.quote = StringIO.new(pdf_string)
    new_pdf.save
  end

end

Со скрепкой раньше все работало нормально. Хотя с shrine, ничего не сохраняется в столбце quote_data новой записи quotepdf. Рабочий также не возвращает ошибок.

Кэшированный файл действительно загружен в корзину S3, поэтому файл PDF создается правильно. Окончательный файл отсутствует.

ИЗМЕНИТЬ

заставил его работать, сняв мой загрузчик до нуля:

class QuotesAndInvoicesUploader < Shrine

    def generate_location(io, context)
        type  = context[:record].class.name.downcase if context[:record]
        name  = super 

        [type, name].compact.join("/")
    end

end

Но я не понимаю, почему раньше это не удалось: файл всего 22 КБ и действительно PDF. Не может быть проблемой проверки ..

ИЗМЕНИТЬ 2

Обнаружен тип mimetype действительно null

{"id":"devispdf/04aa04646f73a3710511f851200a2895","storage":"store","metadata":{"filename":null,"size":21613,"mime_type":null}}

Хотя в моем инициализаторе Shrine.plugin :determine_mime_type


person Maxence    schedule 02.03.2019    source источник


Ответы (1)


В своей фоновой работе попробуйте посмотреть, что это даст:

Shrine.determine_mime_type(StringIO.new(pdf_string))

Если это nil, то я бы порекомендовал попробовать другой анализатор (например, :mimemagic или :marcel).

Shrine.plugin :determine_mime_type, analyzer: :mimemagic
# or
Shrine.plugin :determine_mime_type, analyzer: :marcel

Если это не удается, вы также можете использовать анализатор на основе расширений, такой как :mime_types или :mini_mime, и в фоновом задании назначить временный файл с расширением:

tempfile = Tempfile.new(["quote", ".pdf"], binmode: true)
tempfile.write pdf_string
tempfile.open # flush & rewind

new_pdf = @quote.build_quotepdf
new_pdf.quote = tempfile
new_pdf.save! # fail loudly if save fails

В качестве альтернативы, поскольку вы подключаетесь в фоновом режиме, вы можете просто полностью отказаться от временного хранения и проверки:

pdf_file = StringIO.new(pdf_string)
uploaded_file = new_pdf.quote_attacher.store!(pdf_file)
new_pdf.quote_data = uploaded_file.to_json
new_pdf.save!
person janko-m    schedule 03.03.2019
comment
Большое спасибо, Янко. Фактически Shrine.determine_mime_type(StringIO.new(pdf_string)) фактически возвращает application/pdf. Так что не очень уверен, почему проверка не удалась. Но ваша правильная проверка на самом деле не нужна. И я использовал ваше решение для обхода файла кеша. Заполненные метаданные действительно показывают правильный тип пантомимы (экранированный). Имя файла по-прежнему необходимо указать вручную. Но все хорошо. - person Maxence; 03.03.2019