升级到 Rails 6.1 后扩展视图生成 PDF returns 错误
Extending view to generate PDF returns error after upgrade to Rails 6.1
直到最近,我才扩展 Rails 视图以在服务对象中生成 PDF:
view = ActionView::Base.new(ActionController::Base.view_paths, {})
view.extend(ApplicationHelper)
view.extend(Rails.application.routes.url_helpers)
WickedPdf.new.pdf_from_string(
view.render(
pdf: pdf_title,
template: template,
locals: { timesheet: timesheet },
print_media_type: true,
orientation: 'Portrait',
page_size: 'A4'
)
)
升级到Rails6.1后,报错,因为这行有变化:
view = ActionView::Base.new(ActionController::Base.view_paths, {})
根据 Rails 来源中的此提交,现在有第三个参数 controller
是强制性的。
这个:
def initialize(lookup_context, assigns = {}, controller = nil)
改为:
def initialize(lookup_context, assigns, controller)
但我不确定在这种情况下 controller
是什么以及我应该提供什么作为第三个参数,因为这都是从服务对象而不是控制器调用的。另外,只添加一个 nil
值作为第三个参数是行不通的,因为打开时 PDF 不可读,所以我猜它不能正确扩展视图。
那么知道要提供什么值作为第三个参数吗?
如果您使用其中一个基本控制器而不是视图来进行渲染,您也许能够获得所需的 html。使用已经包含路由和视图助手的控制器也将减少手动 extends/include 它们的需要。
WickedPdf.new.pdf_from_string(
ApplicationController.renderer.render(
pdf: pdf_title,
template: template,
locals: { timesheet: timesheet },
print_media_type: true,
orientation: 'Portrait',
page_size: 'A4'
)
)
直到最近,我才扩展 Rails 视图以在服务对象中生成 PDF:
view = ActionView::Base.new(ActionController::Base.view_paths, {})
view.extend(ApplicationHelper)
view.extend(Rails.application.routes.url_helpers)
WickedPdf.new.pdf_from_string(
view.render(
pdf: pdf_title,
template: template,
locals: { timesheet: timesheet },
print_media_type: true,
orientation: 'Portrait',
page_size: 'A4'
)
)
升级到Rails6.1后,报错,因为这行有变化:
view = ActionView::Base.new(ActionController::Base.view_paths, {})
根据 Rails 来源中的此提交,现在有第三个参数 controller
是强制性的。
这个:
def initialize(lookup_context, assigns = {}, controller = nil)
改为:
def initialize(lookup_context, assigns, controller)
但我不确定在这种情况下 controller
是什么以及我应该提供什么作为第三个参数,因为这都是从服务对象而不是控制器调用的。另外,只添加一个 nil
值作为第三个参数是行不通的,因为打开时 PDF 不可读,所以我猜它不能正确扩展视图。
那么知道要提供什么值作为第三个参数吗?
如果您使用其中一个基本控制器而不是视图来进行渲染,您也许能够获得所需的 html。使用已经包含路由和视图助手的控制器也将减少手动 extends/include 它们的需要。
WickedPdf.new.pdf_from_string(
ApplicationController.renderer.render(
pdf: pdf_title,
template: template,
locals: { timesheet: timesheet },
print_media_type: true,
orientation: 'Portrait',
page_size: 'A4'
)
)