2016-04-08 108 views
1

我一直在寻找的年龄,我仍然不能似乎想出解决办法,附加对虾PDF以电子邮件

我目前使用的prawn gem,我希望能够在我invoice controllers附加pdfemailcreate action。我目前能够链接到我的invoices/show页面生成的pdf到http://localhost:3000/invoices/297.pdf,但我无法弄清楚如何将此PDF附加到电子邮件。

目前,我没有在任何地方保存生成的PDF和我的邮件看起来像这样

梅勒

class InvoiceMailer < ActionMailer::Base 
default :from => "[email protected]" 

def invoice_email(user) 
    @user = user 
    mail(:to => user.email, :subject => "Invoice Recieved") 
end 
end 

而且我InvoicesController创建操作

{...} 
respond_to do |format| 
    if @invoice.save 
    InvoiceMailer.invoice_email(@invoice.user).deliver 
    format.html { redirect_to invoice_url(@invoice, back_path: 
{...} 

如何添加我的发票这封邮件的附件?我需要在发送之前将发票存储在某个地方吗?

回答

2

您如何做到这一点取决于PDF生成需要多长时间和/或您的服务器放置了多少负载,以及您是否在意这一点。在我的情况下,我从用户生成的内容生成PDF,并且我看到一些PDF创建时间在30多秒范围内。解决这个问题变成了一个运行工作 - 别的地方 - 缓存 - 它(无论是数据库还是云存储)的问题。

@toddmetheny非常适合为所有人提供云存储,但最简单的解决方案。如果您使用短暂存储托管Heroku之类的东西,或者将用户请求中的电子邮件发送(例如,再次使用Heroku,Web dynos与工作者dynos)分离PDF创建,它会变得更有趣。您可以将PDF生成为本地临时文件,但当您需要在运行“工作人员”的邮件程序中读取该临时文件时,该临时文件可能不存在。

真正简单的选项

在您的邮件程序,你可以生成PDF到本地文件,读回内存,然后将其附加:

def invoice_email(user) 
    @user = user 

    attachments['filename_for_user.pdf'] = generate_pdf_content 

    mail(:to => user.email, :subject => "Invoice Recieved") 
end 

private 

    # I had troubles trying to get Prawn to generate 'in memory' 
    # so just write to, then read, then unlink a tempfile 
    def generate_pdf_content 
    pdf = some_method_that_generates_a_prawn_pdf_object 
    Tempfile.create do |f| 
     pdf.render_file f 
     f.flush 
     File.read(f) 
    end 
    end 

我建议你先在这里得到事情工作。

更复杂的选项,您可能要生成PDF文档(这可能需要很长的时间),从发送电子邮件的工作,这通常是更快的工作分开

一天。我这样做的方式是创建一个生成PDF到本地Tempfile的作业,然后将该文件上传到S3存储并记录S3对象ID(我在我的数据库中执行此操作,您可以将它作为工作属性欺压)。

完成后,该作业会创建一个新的邮件作业。邮件作业(可以在不同的服务器上执行)将S3存储中的PDF从本地文件下载到本地文件,然后将其添加到电子邮件中,就像上面的简单选项一样。

1

您需要一个可以使用的网址。如果您不想将其存储在数据库中,则任何云存储解决方案都是一种选择。

下面是从rails guides on action mailer添加附件,以邮寄的一些相关信息:

2.3.1添加附件

行动梅勒使得它很容易添加附件。

传递文件名和内容,Action Mailer和Mail gem会自动猜测mime_type,设置编码并创建附件。

attachments['filename.jpg'] = File.read('/path/to/filename.jpg') 

当邮件方法将被触发,它将发送一个多部分电子邮件中的附件,正确嵌套与顶部电平是多部分/混合,然后将第一部分是包含多部分/替代纯文本和HTML电子邮件。

相关问题