使用 Rails 5.2 ActiveStorage 创建和保存 pdf 并稍后附加到电子邮件

Posted

技术标签:

【中文标题】使用 Rails 5.2 ActiveStorage 创建和保存 pdf 并稍后附加到电子邮件【英文标题】:Use Rails 5.2 ActiveStorage to create and save pdf and later attach to email 【发布时间】:2018-06-24 10:08:56 【问题描述】:

恐怕我在使用新的主动存储功能时完全搞错了。 我想要做的是创建一个 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 

第一部分仍然缺失。希望有人能解答!

【问题讨论】:

我不能说主动存储,但我可以告诉你,你绝对可以从字符串创建电子邮件附件。我每天都有很多次生产代码。只是为了测试,将document.blob 替换为'this is a test' 并确认附件在那里。问题可能出在主动存储的第一部分。 【参考方案1】:

我相信,如果您要生成 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,但暂时没有。除非您请求文件,否则大多数生成方法似乎都返回一个字符串。您可能已经知道这一点 - 只是提供一些背景知识。

由于 wicked_pdf 可以返回字符串,我认为您可以使用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 一起使用,就像你有一个打开的文件一样。

然后,正如您在更新的问题中提到的,您可以下载文件并将其附加到电子邮件中。

【讨论】:

感谢您的回答,但这正是我面临的问题。如果我这样做,我必须在光盘上创建一个文件,在这个过程中我不需要两次。有没有办法在不写入磁盘的情况下实现它?类似于从字符串创建附件?用于邮件和 ActiveStorage。 @MarkusAndreas 请更新您的问题以包括“不写入磁盘”部分。也许还可以提供一些背景知识,说明您需要以这种方式做事。 @MarkusAndreas 我做了更多研究并更新了这个答案。希望对您有所帮助。 非常感谢您的更新!这就像一个魅力!

以上是关于使用 Rails 5.2 ActiveStorage 创建和保存 pdf 并稍后附加到电子邮件的主要内容,如果未能解决你的问题,请参考以下文章

将 Rails 5.2 升级到 6.0.0 后内存泄漏

在 Rails 5.2 中禁用活动存储

在 Postgresql 中使用 UUID 的 Rails 5.2 活动存储

Rails 5.2 MiniMagick::Error 使用具有比率和活动存储的图像变体时

带有 master.key 的 Rails 5.2 - Heroku 部署

Rails 5.2 数据表不会在页面更改时刷新数据