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_string
在 pdfemail
时也有效。
第三次尝试:
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
中调用 render
、render_to_string
和 flash[: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 不使用任何控制器实例方法,例如 render
、render_to_string
或 flash
,必须小心因为您 无法异步处理控制器操作 。因此,您必须传入所需的数据,在本例中为 costproject_ids
、useremail
来自 current_user.email
。
在 PdfMailer
class 中,您必须使用不同于控制器 render_to_string
的其他方法在该循环中生成 pdf。这里有很多其他工具:https://www.ruby-toolbox.com/categories/pdf_generation.
在您的第 3 次尝试中:它不起作用,因为您正在实例化一个新的控制器,其中没有设置 @costproject 实例变量。
我有一个页面,用户可以在其中 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_string
在 pdfemail
时也有效。
第三次尝试:
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
中调用 render
、render_to_string
和 flash[: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 不使用任何控制器实例方法,例如 render
、render_to_string
或 flash
,必须小心因为您 无法异步处理控制器操作 。因此,您必须传入所需的数据,在本例中为 costproject_ids
、useremail
来自 current_user.email
。
在 PdfMailer
class 中,您必须使用不同于控制器 render_to_string
的其他方法在该循环中生成 pdf。这里有很多其他工具:https://www.ruby-toolbox.com/categories/pdf_generation.
在您的第 3 次尝试中:它不起作用,因为您正在实例化一个新的控制器,其中没有设置 @costproject 实例变量。