ruby-on-rails - guides - rails active storage s3



Use Rails 5.2 ActiveStorage para crear y guardar archivos PDF y luego adjuntarlos al correo electr├│nico (1)

Me temo que me estoy equivocando completamente con la nueva función de almacenamiento activo. Lo que quiero hacer es crear un pdf (estoy usando WickedPdf) y adjuntarlo a un modelo. Aquí está el primer problema. La única posibilidad que he descubierto hasta ahora es escribir primero en un archivo y luego abrir este archivo para crear el archivo adjunto.

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

¿Hay una manera de crear el archivo adjunto de una cadena?

Después intento adjuntar este archivo a un correo. Esto falla porque necesita un archivo de nuevo, no un blob.

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

Crear un archivo de nuevo me parece realmente extraño.

¿Puede complacer a alguien que me ilumine cuál es la forma correcta de lograrlo sin escribir ningún archivo? Me parece innecesario, ineficiente y me consume mucho tiempo.

=====

Solución Parte 2: Así que logré adjuntar el documento sin crear un archivo

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

La primera parte todavía falta. Espero que alguien tenga una respuesta!


Creo que si está generando algo como un PDF, querrá usar la opción io cuando lo adjunte. Así es como estoy haciendo las cosas en una aplicación ahora.

Por ejemplo, esto es lo que muestra la documentación :

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

Como aparece en la documentación, a menos que tenga un ActionDispatch::Http::UploadedFile , querrá usar la opción io .

En cuanto a adjuntar el archivo a un correo electrónico, puede tener un par de opciones. Si aún tiene acceso a pdf_document , puede hacer esto. Aunque no estoy seguro de qué tipo de objeto es exactamente.

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

Actualizar

He usado wicked_pdf anteriormente, pero no por un tiempo. Parece que la mayoría de los métodos de generación devuelven una cadena a menos que solicite un archivo en su lugar. Es posible que ya lo sepas, solo que ofrezcas algunos antecedentes para la respuesta.

Como wicked_pdf puede devolver una cadena, creo que puedes usar StringIO para adjuntar el archivo. Por ejemplo:

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

StringIO hace exactamente lo que su nombre indica. Toma una cuerda y hace que se comporte como un IO. Una vez que tenga un IO, puede usarlo con ActiveStorage como si tuviera un archivo abierto.

Luego, como mencionó en su pregunta actualizada, puede descargar el archivo y adjuntarlo al correo electrónico.