使用 Rails 5.2 ActiveStorage 创建和保存 pdf 并稍后附加到电子邮件
Use Rails 5.2 ActiveStorage to create and save pdf and later attach to email
恐怕我对新的活动存储功能完全不满意。
我想要做的是创建一个 pdf(我正在使用 WickedPdf)并将其附加到模型。
这是第一个问题,到目前为止我想出的唯一机会是先写入一个文件,然后打开这个文件来创建附件。
self.document.attach( {
filename: "filename.pdf",
io: File.open(pdf_document)
})
有没有办法从字符串创建附件?
然后我尝试将此文件附加到邮件中。这失败了,因为它再次需要一个文件,而不是一个 blob。
attachments[document.filename.to_s] = document.blob
再次创建文件对我来说真的很奇怪。
谁能告诉我在完全不写文件的情况下实现该目标的正确方法是什么?对我来说,我似乎是不必要的、低效的和耗时的。
=====
解决方案第 2 部分:
所以我设法在不创建文件的情况下附加了文档
attachments[document.filename.to_s] = {:mime_type => 'application/pdf',
:content => document.attachment.blob.download }
第一部分仍然缺失。希望有人能回答!
我相信如果您要生成类似 PDF 的文件,您会希望在附加时使用 io
选项。这就是我现在在应用程序中做事的方式。
例如,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
如文档中所示,除非您有 ActionDispatch::Http::UploadedFile
,否则您需要使用 io
选项。
至于将文件附加到电子邮件中,您可能有几种选择。如果您仍然可以访问 pdf_document
,您可以这样做。我不确定它到底是什么类型的对象。
attachments[document.filename.to_s] = pdf_document.read
更新
我以前用过 wicked_pdf,但暂时不用了。它看起来像大多数生成方法 return 一个字符串,除非你请求一个文件。您可能已经知道这一点 - 只是为答案提供一些背景知识。
既然wicked_pdf可以return一个字符串,我想你可以使用StringIO
来附加文件。例如:
pdf = WickedPdf.new.pdf_from_string("<h1>Hey</h1>")
self.document.attach(io: StringIO.new(pdf), filename: "file.pdf", content_type: "application/pdf")
StringIO 的作用正如其名。它接受一个字符串并使其表现为一个 IO。有了 IO 后,就可以像打开文件一样将其与 ActiveStorage 一起使用。
然后,正如您在更新的问题中提到的,您可以下载该文件并将其附加到电子邮件中。
恐怕我对新的活动存储功能完全不满意。 我想要做的是创建一个 pdf(我正在使用 WickedPdf)并将其附加到模型。 这是第一个问题,到目前为止我想出的唯一机会是先写入一个文件,然后打开这个文件来创建附件。
self.document.attach( {
filename: "filename.pdf",
io: File.open(pdf_document)
})
有没有办法从字符串创建附件?
然后我尝试将此文件附加到邮件中。这失败了,因为它再次需要一个文件,而不是一个 blob。
attachments[document.filename.to_s] = document.blob
再次创建文件对我来说真的很奇怪。
谁能告诉我在完全不写文件的情况下实现该目标的正确方法是什么?对我来说,我似乎是不必要的、低效的和耗时的。
=====
解决方案第 2 部分: 所以我设法在不创建文件的情况下附加了文档
attachments[document.filename.to_s] = {:mime_type => 'application/pdf',
:content => document.attachment.blob.download }
第一部分仍然缺失。希望有人能回答!
我相信如果您要生成类似 PDF 的文件,您会希望在附加时使用 io
选项。这就是我现在在应用程序中做事的方式。
例如,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
如文档中所示,除非您有 ActionDispatch::Http::UploadedFile
,否则您需要使用 io
选项。
至于将文件附加到电子邮件中,您可能有几种选择。如果您仍然可以访问 pdf_document
,您可以这样做。我不确定它到底是什么类型的对象。
attachments[document.filename.to_s] = pdf_document.read
更新
我以前用过 wicked_pdf,但暂时不用了。它看起来像大多数生成方法 return 一个字符串,除非你请求一个文件。您可能已经知道这一点 - 只是为答案提供一些背景知识。
既然wicked_pdf可以return一个字符串,我想你可以使用StringIO
来附加文件。例如:
pdf = WickedPdf.new.pdf_from_string("<h1>Hey</h1>")
self.document.attach(io: StringIO.new(pdf), filename: "file.pdf", content_type: "application/pdf")
StringIO 的作用正如其名。它接受一个字符串并使其表现为一个 IO。有了 IO 后,就可以像打开文件一样将其与 ActiveStorage 一起使用。
然后,正如您在更新的问题中提到的,您可以下载该文件并将其附加到电子邮件中。