Прикрепить креветки pdf к электронной почте


Я искал целую вечность и до сих пор не могу этого понять,

В настоящее время я использую prawn gem и хочу иметь возможность присоединить pdf к email в моем invoice controllers create action. В настоящее время я могу ссылаться на сгенерированный pdf с моей страницы invoices/show через http://localhost:3000/invoices/297.pdf, но я не могу понять, как прикрепить этот pdf к электронной почте.

В настоящее время я нигде не храню сгенерированный PDF, и мой почтовый ящик выглядит так

Мейлер

class InvoiceMailer < ActionMailer::Base
default :from => "notifications@example.com"

 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 2

2 ответа:

То, как вы это делаете, зависит от того, сколько времени занимает генерация PDF и/или сколько нагрузки она помещает на ваш сервер, и заботитесь ли вы об этом. В моем случае я создавал PDF-файлы из пользовательского контента, и я видел, что некоторые времена создания PDF увеличились в диапазоне 30+ секунд. Решение этой проблемы становится проблемой выполнения задания где-то еще и кэширования (будь то БД или облачное хранилище).

@toddmetheny совершенно прав, предлагая облачное хранилище для всех, кроме самых простых решений. Он получает больше интересно, если вы размещаете что-то вроде Heroku с эфемерным хранилищем, или если вы отделяете создание PDF от отправки электронной почты от запросов пользователей (например, от Heroku again, web dynos vs worker dynos). Вы можете сгенерировать 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 в локальный Темпфайл, затем загружает этот файл в хранилище S3 и записывает идентификатор объекта S3 (я делаю это в своей базе данных, вы можете просто сделать это в качестве атрибута работы вы толкаетесь).

По завершении этого задания создается новое задание почтовой службы. Задание mailer (которое может выполняться на другом сервере) загружает PDF-файл из хранилища S3 в локальный файл, а затем добавляет его к электронной почте, как и простой вариант выше.

Вам понадобится url-адрес, с которым вы можете работать. Любое решение облачного хранилища-это вариант, если вы не хотите хранить его в своей базе данных.

Вот некоторые важные сведения о добавлении вложений в почтовые программы из направляющих rails на action mailer :

2.3.1 Добавление Вложений

Action Mailer позволяет очень легко добавлять вложения.

Передайте имя файла, содержимое и действие почтовой программы, и Почтовая жемчужина автоматически угадает тип mime_type, установит кодирование и создание вложения.

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

Когда метод mail будет запущен, он отправит составное электронное письмо с вложением, должным образом вложенным с верхним уровнем, являющимся составным / смешанным, и первой частью, являющейся составным / альтернативным, содержащим обычный текст и сообщения электронной почты HTML.