我有一个页面,用户可以选择多个costprojects
来创建单个pdf(包括S3附件)。它工作正常 - 除非用户选择了不少,否则app会超时(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_string
仅在pdfemail
时才有效。
第3次尝试:
pdf2 = CostprojectsController.new.render_to_string pdf: "SLCO Captital Projects.pdf", template: "costprojects/viewproject", encoding: "UTF-8"
第3次尝试时,@costproject
未传递给costprojects / viewproject.pdf.erb
答案 0 :(得分:0)
您无法异步处理控制器操作。
并且您无法在类方法render
中调用render_to_string
,flash[:notice]
和self.pdfemail
等控制器方法,因为这些方法是控制器上的实例方法。 / p>
您必须从控制器响应逻辑中分离出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
类不使用任何控制器实例方法,例如render
,render_to_string
或flash
,因为您必须在控制器中处理这些方法无法异步处理控制器操作。因此,您必须传递所需的数据,在这种情况下,来自costproject_ids
的{{1}},useremail
。
在current_user.email
类中,您必须使用除控制器PdfMailer
之外的其他方法在该循环中生成pdf。这里还有很多其他工具:https://www.ruby-toolbox.com/categories/pdf_generation。
第3次尝试:它无法正常工作,因为您正在实例化一个没有设置@costproject实例变量的新控制器。