Discussion Forums
- Topic List
- Most Recent Posts
- Sign In for more options
Hi,
I've got a form and I'd like to send the value of that form as an attachement (pdf) to me. The generation of that pdf works fine (with prawn), thanks to the railscast, but could someone tell me how I could put that file as an attachement in my mail?
I'd like to only make it possible that only the send action could access/generate that pdf. How could I do this?
Refer to Rails API of ActionMailer::Base about sending mails with attachments. According to the document that you could just pass the content of generated PDF as params of the mailer class, looks like this:
def generated_pdf(recipient, pdf)
attachment "application/pdf" { |a| a.body = pdf }
end
FYI, to get the content of generated PDF, the "render_as_string" method and read the response.body after rendering automatically will be both useful in this situation.
And how can I then generate the pdf document? Like the railscast, I just had to create a .pdf.prawn document and that's it.
You can move the logic that creates the pdf from the .prawn file to your controller or even better to a model. You will want to use pdf = Prawn::Document.new and the render method to create a string version of the pdf which can be attached to the email.
Check out http://prawn.majesticseacreature.com/docs/prawn-core/classes/Prawn/Document.html#M000097 and http://prawn.majesticseacreature.com/docs/prawn-core/classes/Prawn/Document.html#M000101.
You do not need the real PDF file as attachment. Actually, only the generated content (binary stream) of this pdf document is necessary. You can access to this stream via response object. Your codes of controller should looks like the following:
def show # just a example render # force to generate pdf using prawnto so we can access to the response object pdf = response.body YourMailer.deliver_generated_pdf(current_user, pdf) end
I'm sorry for my late response, I had some last exams.
On topic :
I've tried to generate a pdf in my controller (that didn't go so fine), but recently I found this site (http://dizzy.co.uk/ruby_on_rails/cheatsheets/action-mailer#multipart_messages), and I quote
ActionMailer will automatically detect and use multipart templates, where each template is named after the name of the method, followed by the content type. Each such detected template will be added as a separate part to the message. For example:
signup_notification.text.plain.erb signup_notification.text.html.erb signup_notification.text.xml.builder
Each would be rendered and added as a separate part to the message with the corresponding content type. The same body hash is passed to each template.
So in my notifier view folder I created a send_mail.html.erb template and a send_mail.pdf.prawn, but when I send the email, the pdf attachement isn't added.
Could anyone tell me if this info is correct and what I'm doing wrong? http://pastie.org/551464
Hi Wouter,
How about this?
In your controller, you generate the PDF file:
Prawn::Document.new do
text "THIS IS A PDF"
end.render
Notifier.deliver_signup_notification(customer_email, pdf_file)
In your notifier action mailer:
def signup_notification(customer_email, pdf_file)
@from = "example@email.com"
@recipients = customer_email
@subject = "Reactie"
@sent_on = Time.now
@content_type = "text/html"
attachment :content_type => "application/octet-stream", :filename => "your_file_name_here.pdf", :body => pdf_file
end
Hope that helps. Something wrong with format here, so I paste the code in "here":http://pastie.org/554806
Sonny
Thanks Sonny, that's working fine but the problem is that I have 200 and more lines of code for generating the pdf and I'd like to keep it out of my controller so that it can stay clean. Isn't there a way to render some kind of template ( a .pdf.prawn) and include that in my Notifier.deliver methode?
Wouter,
Have you ever managed to get this working? I'm attempting to do the same thing. Basically what I want to do is have my model access the prawn pdf so I can easily attach the file when I send the email out. I found that you do it from the controller using: @output = render_to_string :template => 'invoices/show.pdf.prawn', :layout => false
But apparently you can't use render_to_string in the model or in a rake task. For a model and rake task I found these articles http://www.compulsivoco.com/2008/10/rendering-rails-partials-in-a-model-or-background-task/ http://www.gregorydoran.co.uk/2009/08/ruby-on-rails-rendering-views-outside-of-the-controller/ http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/14f5f3f6f7819d27
following those I figured in my Invoice Model I could do something like this
def pdf_file
av = ActionView::Base.new(Rails::Configuration.new.view_path)
av.extend ApplicationController.master_helper_module
output = av.render(
:file => 'invoices/show.pdf.prawn',
:locals => {:invoice => self},
:layout => false
)
end
My ideas was in my mailer I could attach the file using something like this.
def test(user, invoice)
recipients user.email
from "Testing "
subject "Email Testing"
body :user => user
content_type "text/html"
attachment "application/pdf" do |a|
a.body = invoice.pdf_file
end
end
But in the end I'm stuck with a weird prawn error
ActionView::TemplateError: ActionView::TemplateError (You have a nil object when you didn't expect it! The error occurred while evaluating nil.compute_prawnto_options) on line #1 of app/views/invoices/show.pdf.prawn: 1: pdf.text "Invoice ##{@invoice.id}", :size => 30, :style => :bold 2: pdf.text "#{@invoice.user.firstname} #{@invoice.user.lastname}", :size => 20 3: pdf.text "#{@invoice.user.address1}", :size => 20 ......
I know I'm not offering any solution but maybe some of this might point you into the right direction. Let me know if you ever get it working.
Austin,
I didn't manage to fix this problem, I keep sending the mails in plain text rather than in pdf.
