2016-04-08 57 views
1

Ich habe seit Ewigkeiten gesucht und ich kann nicht scheinen, noch um dies herauszufinden,Attach pdf Garnelen auf E-Mail

Ich bin derzeit die prawn gem mit und ich möchte ein pdf zu einem email in meinem invoice controllers befestigen können, create action. Ich bin im Moment in der Lage, zu einem erzeugten pdf von meiner invoices/show Seite durch http://localhost:3000/invoices/297.pdf zu verbinden, aber ich kann nicht herausfinden, wie man dieses pdf an eine eMail anfügt.

Zur Zeit bin ich nicht die Speicherung der erzeugten PDF überall und mein Mailer sieht wie folgt aus

Mailer

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

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

Und meine InvoicesController Aktion erstellen

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

Wie kann ich meine Rechnung als hinzufügen ein Anhang zu diesem Mailer? Muss ich die Rechnung irgendwo aufbewahren, bevor ich sie abschicken kann?

Antwort

2

Wie Sie dies tun, hängt davon ab, wie lange die PDF-Generierung dauert und/oder wie viel es auf Ihren Server lädt und ob Sie sich darum kümmern. In meinem Fall habe ich PDFs aus User-Generated-Content generiert und einige PDF-Erstellungszeiten im Bereich von 30+ Sekunden erreicht. Lösen für das wird ein run-the-job-wood-else und cache-it (ob DB oder Cloud-Speicher) Problem.

@toddmetheny hat recht, wenn er Cloud-Speicher für alle außer den einfachsten Lösungen vorschlägt. Es wird interessanter, wenn Sie auf etwas wie Heroku mit ephemeren Speicher hosten, oder wenn Sie PDF-Erstellung von E-Mail-Senden von Benutzeranfragen trennen (z. B. von Heroku wieder, Web-Dynas vs. Worker-Dynos). Sie können die PDF-Datei in einer lokalen temporären Datei generieren, aber diese temporäre Datei ist möglicherweise nicht vorhanden, wenn Sie sie in Ihrem Mailer lesen müssen, der auf einem 'Worker' ausgeführt wird.

Wirklich einfache Option

In Ihrem Mailer Sie das PDF in eine lokale Datei erzeugen könnte, es wieder in den Speicher geladen, dann bringen Sie es:

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 

Ich schlage vor, Sie hier beginnen zu bekommen Dinge arbeiten.

Kompliziertere Option

Eines Tages möchten Sie vielleicht den Job trennen, die das PDF erzeugt (das eine lange Zeit in Anspruch nehmen kann) von den Jobs, die E-Mail senden, die schneller in der Regel viel sind. Die Art, wie ich dies tue, ist ein Job, der die PDF in eine lokale Tempdatei generiert, diese Datei dann in S3-Speicher hochlädt und die S3-Objekt-ID aufzeichnet (ich mache es in meiner Datenbank, Sie könnten es einfach als Jobattribut machen herumschubsen).

Wenn dieser Job abgeschlossen ist, wird ein neuer Mailer-Job erstellt. Der Mailer-Job (der auf einem anderen Server ausgeführt werden kann) lädt die PDF-Datei aus dem S3-Speicher in eine lokale Datei und fügt sie dann der E-Mail hinzu, ähnlich wie die einfache Option oben.

1

Sie benötigen eine URL, mit der Sie arbeiten können. Jede Cloud-Speicherlösung ist eine Option, wenn Sie sie nicht in Ihrer Datenbank speichern möchten.

Hier einige relevante Informationen über das Hinzufügen von Attachments zu Mailer von rails guides on action mailer:

2.3.1 Hinzufügen von Attachments

Aktion Mailer macht es sehr einfach, Anhänge hinzuzufügen.

Übergeben Sie den Dateinamen und den Inhalt und Action Mailer und das Mail-Juwel wird automatisch den mime_type erraten, die Kodierung einstellen und den Anhang erstellen.

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

Wenn der Mail-Methode ausgelöst wird, wird es eine mehrteilige Nachricht mit einem Anhang senden, korrekt verschachtelt mit der obersten Ebene ein mehrteiliger/alternative sein, welche die multipart/mixed, und wobei der erste Teil Nur-Text- und HTML-E-Mail-Nachrichten.