Rails 3 -Вывод PDF из просмотра и прикрепление к электронной почте

#ruby-on-rails #ruby-on-rails-3 #pdf-generation #actionmailer #wicked-pdf

#ruby-on-rails #ruby-on-rails-3 #генерация pdf #actionmailer #wicked-pdf

Вопрос:

Я использовал Wicked_pdf для отображения представления в формате PDF и actionmailer для отправки электронных писем, но я не могу заставить их работать вместе. Я хочу прикрепить PDF-версию определенного представления к электронному письму с помощью actionmailer и отправить его, нажав ссылку или кнопку. У меня есть команда link_to, которая отправляет электронное письмо. Вот мой контроллер, который получает сгенерированное электронное письмо:

 def sendemail
 @user = User.find(params[:id])
 Sendpdf.send_report(@user).deliver
 redirect_to user_path(@user)
 flash[:notice] = 'Email has been sent!'
end  
  

Вот что у меня есть в моем actionmailer:

 class Sendpdf < ActionMailer::Base
default :from => "myemail@email.com"

def send_report(user)
@user = user
  attachment "application/pdf" do |a|
  a.body = #Something should go here, maybe WickedPDF.new.something?
  a.filename = 'MyPDF'
end     
mail(:to => user.email, :subject => "awesome pdf, check it")
end

end
  

Я видел много вопросов и ответов, большинство из которых касаются Prawn. Кажется, что на это должен быть простой ответ. Кто-нибудь может помочь?

ОБНОВЛЕНИЕ Я благодарен за предложение использовать в качестве альтернативного варианта в приведенном ниже ответе. Тем не менее, я действительно хотел бы узнать, как отобразить представление в формате PDF и прикрепить его к моей электронной почте. Я открыт для использования чего-то другого, такого как Prawn или что-нибудь еще, если мне нужно.

Ответ №1:

2 хороших способа сделать это так, как вы хотите:

1: Создайте PDF-файл в контроллере, затем отправьте его по электронной почте в качестве параметра.

 # controller
def sendemail
  @user = User.find(params[:id])
  pdf = render_to_string :pdf => 'MyPDF'
  Sendpdf.send_report(@user, pdf).deliver
  redirect_to user_path(@user)
  flash[:notice] = 'Email has been sent!'
end

# mailer
def send_report(user, pdf)
  @user = user
  attachments['MyPDF.pdf'] = pdf
  mail(:to => user.email, :subject => "awesome pdf, check it")
end
  

2. Создайте PDF непосредственно в почтовой программе (немного сложнее, но может быть вызван из модели)

 def send_report(user)
  @user = user
  mail(:to => user.email, :subject => "awesome pdf, check it") do |format|
    format.text # renders send_report.text.erb for body of email
    format.pdf do
      attachments['MyPDF.pdf'] = WickedPdf.new.pdf_from_string(
        render_to_string(:pdf => 'MyPDF',:template => 'reports/show.pdf.erb')
      )
    end
  end
end
  

Комментарии:

1. Спасибо, что ответили на этот вопрос. В итоге я создал действие для сохранения PDF в файл. Затем в действии по отправке почты я вызвал это действие, прикрепил его к электронной почте, затем стер его из файла. Это плохой способ сделать это? Это отлично работает.

2. Неплохой способ, но иногда запись в файловую систему нежелательна, как на Heroku. Кроме того, будьте осторожны, чтобы ваши файлы не могли быть перемещены или удалены каким-либо другим процессом.

3. @Unixmonkey Просто чтобы добавить к этому, я заметил, что большинство ответов о WickedPDF от вас. Я просмотрел все ваши ответы по максимуму и по минимуму и установил следующее: gist.github.com/anonymous/5229508 но, похоже, не получается это исправить. Кажется, что каждое решение, которое я пробовал, дает мне Template is missing . С нетерпением ждем вашего ответа.

4. Как передать переменные в шаблон, который находится в render_to_string?

5. @CodecPM render_to_string(pdf: 'MyPDF', template: 'reports/show.pdf.erb', locals: { var_1: 'variable 1' }) сделает Variable: <%= var_1 %> доступным шаблон erb.

Ответ №2:

Для этого есть 2 способа.

  1. Либо вы хотите, чтобы PDF-файл был встроен в отправляемое вами электронное письмо, чтобы при загрузке пользователем PDF-файла из электронной почты не было запроса на действие render new pdf для вашего соответствующего контроллера.
    Я не знаю, как сделать это эффективно, потому что я никогда не делал этого раньше.

  2. Или вы просто предоставляете ссылку на PDF в своем электронном письме, и когда пользователь нажимает на нее, вызывается действие для создания pdf, а затем пользователь может загрузить его.
    Таким образом, если загрузка PDF-файлов является большой нагрузкой на сервер, вы можете перенаправить эти запросы куда-нибудь еще. Короче говоря, существует огромный простор для повышения эффективности.

Пример кода для 2-го метода (предоставленный код был написан с использованием PDFKit, поэтому измените соответствующим образом):

 class PdfsController < ApplicationController
  def pdf
    respond_to do |format|
      format.pdf { render :text => wickedPDF.new( Pdf.find(params[:id]).content ).to_pdf }
    end
  end
...
end
  

Замените Pdf.find(params[:id]).content по вашему выбору и to_pdf метод в соответствии с wickedPDF.

Затем вы можете просто передать ссылку для загрузки PDF в своем электронном письме следующим образом

 <%= link_to "Download", pdf_pdf_path(pdf, :format => "pdf") %>
  

или все, что подходит в соответствии с wickedPDF.

Комментарии:

1. Это отличный вариант, на самом деле я об этом не подумал. Если у меня есть выбор, я хотел бы прикрепить PDF к электронному письму, но пока я не разберусь с этим, добавление ссылки «загрузить» в электронное письмо — отличная идея, спасибо!

2. Это не отвечает на поставленный вопрос. Обходные пути часто лучше всего использовать для комментариев, а не ответов.