Ruby:使用group方法时,Prawn PDF内存不足

我想要以PDF格式显示大量产品,并带有类别标题。 如果某个类别不适合当前页面,我想将其移至下一页。 为此,我正在使用Prawn的组方法。

Product.all.group_by(&:category).each do |category, products| pdf.group do # Simplified the data a bit for this example pdf.text category pdf.table products.map{ |p| [p.title, p.price] } end end 

这适用于少量产品,但是当我添加超过100左右时,它需要很长时间,然后以“未能分配内存”结束。 如果我不使用组方法,则需要大约30秒。

显然,组方法不能很好地管理其内存使用。 任何建议的解决方法将不胜感激。

———-更新的答案——–

之前的解决方法对于生产服务器来说还不够好,所以我不得不使用git repo的开发版本作为vendor / prawn下的子模块安装,如下所述: https : //github.com/sandal/prawn/wiki/使用大虾function于Rails的

组方法的内存问题已经消失,但事情的语法/选项有所改变。 所以我不得不重写代码来生成PDF。

此外,让子模块与Rails应用程序的git repo很好地配合也很困难。 部署到生产是艰难的。

———-原始答案——–

这不是一个修复,但它使问题在它自身显示之前需要更多的组迭代:

  • 覆盖名为’group’的Prawn :: Document实例方法
  • 使用来自最新开发版本的prawn(来自github.com)的’group’函数中的代码

我这样做的方式是我将一个文件添加到我的Rails应用程序的/ lib文件夹中。 该文件将包含Prawn gems并定义PDF文档的mime类型:

 class PdfPrawn require 'prawn' require 'prawn/core' require 'prawn/table' MIME_TYPE = "application/pdf" end class Prawn::Document def group(second_attempt=false) old_bounding_box = @bounding_box @bounding_box = SimpleDelegator.new(@bounding_box) def @bounding_box.move_past_bottom raise RollbackTransaction end success = transaction { yield } @bounding_box = old_bounding_box unless success raise Prawn::Errors::CannotGroup if second_attempt old_bounding_box.move_past_bottom group(second_attempt=true) { yield } end success end end 

然后在模型文件中,我定义了一个方法来生成我的PDF并使用这样的东西:

 def to_pdf require "#{File.expand_path(RAILS_ROOT)}/lib/pdf_prawn" pdf = Prawn::Document.new # code to add stuff to PDF pdf.render end 

我在一个项目上使用虾,很遗憾地告诉你,但这是一场灾难,最后我们不得不改用邪恶的pdf 。 我建议你在没有太多代码之前做同样的事情。