Rails 3.2 延迟工作 pdf 电子邮件

Rails 3.2 delayed job a pdf email

我有一个页面,用户可以在其中 select 多个 costprojects 创建一个 pdf(包括 S3 附件)。它工作正常 - 除非用户 select 相当多,然后应用程序将超时(30 秒)。

所以,我想创建 pdf 并在后台使用 gem 'delayed_job_active_record' 将其通过电子邮件发送。

这没有延迟作业:

 def pdfemail
    @costprojects = Costproject.find(params[:costproject_ids])
    pdf = CombinePDF.new
    @costprojects.each do |costproject|
      @costproject = costproject
      pdf2 = render_to_string pdf: "SLCO Captital Projects.pdf", template: "costprojects/viewproject", encoding: "UTF-8"
      pdf << CombinePDF.parse(pdf2)
      costproject.attachments.each do |attachment|
        pdf << CombinePDF.parse( Net::HTTP.get( URI.parse( attachment.attach.url ) ) )
      end
    end
    useremail = current_user.email
    CostpdfMailer.costpdf_email(useremail,pdf).deliver
    redirect_to :back
    flash[:notice] = 'An Email containing a PDF has been sent to you!'
  end

这是我第一次尝试但没有成功 - 我补充说:

handle_asynchronously :pdfemail

我的第二次尝试:

 def pdfemail
    @costprojects = Costproject.find(params[:costproject_ids])
    CostprojectsController.delay.pdfemail2(@costprojects)
  end

  def self.pdfemail2(costprojects)
    @costprojects = costprojects
    pdf = CombinePDF.new
    @costprojects.each do |costproject|
      @costproject = costproject
      pdf2 = render_to_string pdf: "SLCO Captital Projects.pdf", template: "costprojects/viewproject", encoding: "UTF-8"
      pdf << CombinePDF.parse(pdf2)
      costproject.attachments.each do |attachment|
        pdf << CombinePDF.parse( Net::HTTP.get( URI.parse( attachment.attach.url ) ) )
      end
    end
    useremail = current_user.email
    CostpdfMailer.costpdf_email(useremail,pdf).deliver
    redirect_to :back
    flash[:notice] = 'An Email containing a PDF has been sent to you!'
  end

第二次尝试,我得到:

undefined method `render_to_string' for CostprojectsController:Class

同样的 render_to_stringpdfemail 时也有效。

第三次尝试:

pdf2 = CostprojectsController.new.render_to_string pdf: "SLCO Captital Projects.pdf", template: "costprojects/viewproject", encoding: "UTF-8"

第三次尝试时,@costproject 没有传递给 costprojects/viewproject。pdf.erb

您不能异步处理控制器操作。

并且您不能从 class 方法 self.pdfemail 中调用 renderrender_to_stringflash[:notice] 等控制器方法,因为这些方法是实例控制器上的方法。

您必须将 pdf 电子邮件逻辑与控制器响应逻辑分开,如下所示:

def pdfemail      
  pdf_template = render_to_string pdf: "SLCO Captital Projects.pdf", template: "costprojects/viewproject", encoding: "UTF-8"

  PdfMailer.new.pdf_email params[:costproject_ids], current_user.email, pdf_template

  redirect_to :back
  flash[:notice] = 'An Email containing a PDF has been sent to you!'
end

然后在另一个文件中:

class PdfMailer
  def pdf_email(costproject_ids, useremail, pdf_template)
    @costprojects = Costproject.find(costproject_ids)
    pdf = CombinePDF.new

    @costprojects.each do |costproject|
      @costproject = costproject
      # This part needs work, you can't use render_to_string here.
      # You'll have to generate this pdf some other way.
      pdf2 = render_to_string pdf: "SLCO Captital Projects.pdf", template: "costprojects/viewproject", encoding: "UTF-8"
      pdf << CombinePDF.parse(pdf2)

      costproject.attachments.each do |attachment|
        pdf_response = Net::HTTP.get URI.parse(attachment.attach.url)
        pdf << CombinePDF.parse(pdf_response)
      end
    end

    CostpdfMailer.costpdf_email(useremail, pdf).deliver
  end
  handle_asynchronously :pdf_email
end

PdfMailer class 不使用任何控制器实例方法,例如 renderrender_to_stringflash,必须小心因为您 无法异步处理控制器操作 。因此,您必须传入所需的数据,在本例中为 costproject_idsuseremail 来自 current_user.email

PdfMailer class 中,您必须使用不同于控制器 render_to_string 的其他方法在该循环中生成 pdf。这里有很多其他工具:https://www.ruby-toolbox.com/categories/pdf_generation.

在您的第 3 次尝试中:它不起作用,因为您正在实例化一个新的控制器,其中没有设置 @costproject 实例变量。