Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Rails 5.2 ActiveStorage to create and save pdf and later attach to email

I am afraid i am getting something completely wrong with the new active storage feature. What I want to do is to create an pdf ( I am using WickedPdf ) and attach it to a model. Here is the first issue, The only chance i figured out so far is to write to a file first and then open this file to create the attachment.

self.document.attach( {
  filename: "filename.pdf",
  io: File.open(pdf_document)
})

Is there a way to create the attachment from a string?

Afterwards I try attach this file to a mail. This fails because it needs a file again, not a blob.

attachments[document.filename.to_s] = document.blob

Creating a file again seems really weird to me.

Can please someone enlighten me whats the proper way to achieve that without writing files at all? I seems unnecessary, inefficent and time consuming to me.

=====

Solution Part 2: So I managed to attach the document without creating a file

attachments[document.filename.to_s] = {:mime_type => 'application/pdf',
                               :content => document.attachment.blob.download }

Part one is still missing. Hope someone has an answer!

like image 975
Markus Andreas Avatar asked Jan 15 '18 18:01

Markus Andreas


1 Answers

I believe if you're generating something like a PDF, you'll want to use the io option when you attach. That's the way I'm doing things in an application now.

For example, here's what the documentation shows:

person.avatar.attach(params[:avatar]) # ActionDispatch::Http::UploadedFile object
person.avatar.attach(params[:signed_blob_id]) # Signed reference to blob from direct upload
person.avatar.attach(io: File.open("/path/to/face.jpg"), filename: "face.jpg", content_type: "image/jpg")
person.avatar.attach(avatar_blob) # ActiveStorage::Blob object

As it appears in the documentation, unless you have a ActionDispatch::Http::UploadedFile, you'll want to use the io option.

As for attaching the file to an email, you may have a couple options. If you still have access to the pdf_document, you could do this. I'm not sure exactly what type of object it is though.

attachments[document.filename.to_s] = pdf_document.read

Update

I've used wicked_pdf previously, but not for awhile. It looks like most of the generation methods return a string unless you request a file instead. You may already know this - just giving some background for the answer.

Since wicked_pdf can return a string, I think you can use StringIO to attach the file. For example:

pdf = WickedPdf.new.pdf_from_string("<h1>Hey</h1>")
self.document.attach(io: StringIO.new(pdf), filename: "file.pdf", content_type: "application/pdf")

StringIO does exactly as the name implies. It takes a string and makes it behave as an IO. Once you have an IO, you can use it with ActiveStorage as if you had an opened file.

Then, as you mentioned in your updated question, you can download the file and attach it to the email.

like image 116
Derek Hopper Avatar answered Oct 21 '22 12:10

Derek Hopper