В моем приложении 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