Не удается преобразовать изображение в URL: неопределенный метод `polymorphic_url 'для # <ActionView :: Base - PullRequest
0 голосов
/ 04 июля 2018

В моем приложении Rails у меня есть задание на создание PDF-файлов с помощью WickedPDF. Это работало нормально, пока я не перешел на Rails 5.2, теперь я получаю эту ошибку:

ActionView::Template::Error (Can't resolve image into URL: undefined method `polymorphic_url' for #<ActionView::Base:0x0000000004854590>):

Код, где это происходит, это строка в представлении:

image_tag(image)

Это представление взято из задания, которое я полностью добавил ниже. Ошибка происходит при выполнении последнего метода в классе: private def render_image_pdf(view, pdf_name, image), где он отображает PDF.

После отката к Rails 5.1 все снова работает нормально, поэтому я почти уверен, что это как-то связано с добавленной / измененной функцией в Rails 5.2. Так что я должен изменить, чтобы это снова заработало?

Задание PDF:

class SendInvoiceAsAttachmentJob < ApplicationJob
  require 'open-uri'
  queue_as :default

  def perform(target, invoice, send_invoice, to, cc, subject, body1, body2, body3)
    view = ActionView::Base.new(ActionController::Base.view_paths, {})
    view.extend(ApplicationHelper)
    view.extend(Rails.application.routes.url_helpers)

    # Create invoice as PDF
    pdf = Rails.root.join('tmp', "tmp_invoice.pdf")

    File.open(pdf, 'wb') do |file|
      file << render_invoice_pdf(invoice, view, "tmp_invoice.pdf")
    end

    # Add (signed) timesheet as PDF
    projectuser = Projectuser.where(project_id: invoice.project_id, user_id: invoice.user_id).order(:updated_at).last
    if projectuser.blank? or invoice.fixed_price? or invoice.project.service?
      pdf_name = "#{invoice.set_pdf_filename}.pdf"
      pdf_to_email = pdf
    else
      if invoice.timesheet and invoice.timesheet.signed_copy?(projectuser)
        # Download signed copy
        timesheet_copy = TimesheetCopy.where(projectuser_id: projectuser.id, timesheet_id: invoice.timesheet_id).first

        timesheet_file = Rails.root.join('tmp', timesheet_copy.attachment_file_name)
        timesheet_name = timesheet_copy.attachment_file_name

        if timesheet_copy.attachment.url.index("http").blank?
          download = open("https:#{timesheet_copy.attachment.url}")
        else
          download = open(timesheet_copy.attachment.url)
        end
        IO.copy_stream(download, timesheet_file)

        # Push into a PDF when image
        if timesheet_copy.attachment_file_name.index(".pdf") == nil
          timesheet_tmp = Rails.root.join('tmp', "tmp_timesheet.pdf")
          File.open(timesheet_tmp, 'wb') do |file|
            file << render_image_pdf(view, "tmp_timesheet.pdf", timesheet_file)
          end
          timesheet_file = timesheet_tmp
          File.delete Rails.root.join('tmp', timesheet_copy.attachment_file_name)
        end
      else
        # Create timesheet PDF
        timesheet = Timesheet.find(invoice.timesheet_id)
        timesheet_builder = TimesheetBuilder.new(timesheet.month, timesheet.year)

        timesheet_name = "Timesheet #{timesheet.user.full_name} #{I18n.t("date.month_names")[timesheet.month]} #{timesheet.year}"
        timesheet_file = Rails.root.join('tmp', timesheet_name)

        File.open(timesheet_file, 'wb') do |file|
          file << render_timesheet_pdf(timesheet, view, timesheet_name, projectuser, timesheet_builder)
        end
      end

      # Combine the 2 PDF's
      combined_pdf = CombinePDF.new
      combined_pdf << CombinePDF.load(pdf, allow_optional_content: true)
      combined_pdf << CombinePDF.load(timesheet_file, allow_optional_content: true)
      pdf_name = "#{invoice.set_pdf_filename}.pdf"
      combined_pdf.save Rails.root.join('tmp', pdf_name)
      pdf_to_email = Rails.root.join('tmp', pdf_name)

      File.delete(timesheet_file)
    end

    # Send email
    if target == "basecone"
      company = Company.find(invoice.company_id)
      UserMailer.send_pdf_to_basecone(company.basecone_email, pdf_to_email, pdf_name).deliver
    else
      UserMailer.invoice_email(invoice, send_invoice, to, cc, subject, body1, body2, body3, pdf_to_email, pdf_name).deliver
    end

    File.delete(pdf_to_email)
  end

  private def render_invoice_pdf(invoice, view, pdf_name)
    WickedPdf.new.pdf_from_string(
      view.render(
        pdf: pdf_name,
        template: 'admin/invoices/show_as_attachment.pdf.haml',
        locals: { invoice: invoice, copy_invoice: nil },
        print_media_type:  true,
        orientation:       'Portrait',
        page_size:         'A4'
      )
    )
  end

  private def render_timesheet_pdf(timesheet, view, pdf_name, projectuser, timesheet_builder)
    WickedPdf.new.pdf_from_string(
      view.render(
        pdf: pdf_name,
        template: 'timesheets/show_as_attachment.pdf.haml',
        locals: { timesheet: timesheet, timesheet_builder: timesheet_builder, projectuser: projectuser },
        print_media_type:  true,
        orientation:       'Portrait',
        page_size:         'A4'
      )
    )
  end

  private def render_image_pdf(view, pdf_name, image)
    WickedPdf.new.pdf_from_string(
      view.render(
        pdf: pdf_name,
        template: 'admin/invoices/image_timesheet_as_attachment.pdf.haml',
        locals: { image: image },
        print_media_type:  true,
        orientation:       'Portrait',
        page_size:         'A4'
      )
    )
  end
end

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Вместо того, чтобы вручную создавать настройку ActionView (и, следовательно, нужно добавить всех нужных помощников, в которых вы ошибаетесь - я думаю, некоторые переместились), вы можете использовать новый ActionController::Renderer API для выполнения рендеринга вида в контексте произвольного контроллера.

# Very untested; please treat this is syntactically-valid pseudocode...

WickedPdf.new.pdf_from_string(
  ApplicationController.render(
    template: 'admin/invoices/show_as_attachment.pdf.haml',
    assigns: {
      pdf: pdf_name,
      print_media_type: true,
      orientation: 'Portrait',
      page_size: 'A4',
    },
    locals: { invoice: invoice, copy_invoice: nil },
  )
)
0 голосов
/ 04 июля 2018

Использовать wicked_pdf_image_tag Вместо image_tag

<%=wicked_pdf_image_tag image%>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...