如何从 Rails 中的活动存储关联在邮件程序中附加图像

hel*_*ion 2 actionmailer ruby-on-rails-5 rails-activestorage

在 Rails 5.2 中,我有一个使用 has_many_attached :images 的模型。我想发送一封电子邮件,其中包含所有关联图像作为附件。

我的邮件程序方法目前如下所示:

def discrepancy_alert(asset_discrepancy_id, options={})
  @asset_discrepancy = AssetDiscrepancy.find asset_discrepancy_id
  @asset_discrepancy.images.each_with_index do |img,i|
    attachments["img_#{ i }"] = File.read(img)
  end
  mail to: 'noone@gmail.com', subject: "email subject"
end
Run Code Online (Sandbox Code Playgroud)

显然,File.read 在这里不起作用,因为 img 不是路径,它是一个 blob。我在文档中找不到任何相关信息

问题一:

有没有一种 Rails 方法可以附加这样的斑点?

我可以使用以下内容代替:

@asset_discrepancy.images.each_with_index do |img,i|
  attachments["img_#{ i }"] = img.blob.download
end
Run Code Online (Sandbox Code Playgroud)

问题二:

下载方法可能会使用 RAM 日志,这种用法是否不明智?

看来,随着 ActiveStorage 的添加,rails 邮件程序将拥有一些用于两者之间交互的新方法......我在文档中没有看到任何内容。所有邮件程序附件[]示例都使用本地文件的路径。

小智 5

在应用程序/mailers/mailer.rb中:

if @content.image.attached? 
  @filename = object.id.to_s + object.image.filename.extension_with_delimiter
  if ActiveStorage::Blob.service.respond_to?(:path_for)
    attachments.inline[@filename] = File.read(ActiveStorage::Blob.service.send(:path_for, object.image.key))
  elsif ActiveStorage::Blob.service.respond_to?(:download)
    attachments.inline[@filename] = object.image.download
  end
end
Run Code Online (Sandbox Code Playgroud)

在邮件视图中:

if @filename
  image_tag(attachments[@filename].url)
else
  image_tag(attachments['placeholder.png'].url)
end
Run Code Online (Sandbox Code Playgroud)

  • 谨防。仅当文件存储在本地时这才有效。对于 Google Storage 或 Amazon S3 来说,它会失败。 (3认同)