首页 > 解决方案 > 如何在 Rails 中的活动存储关联中附加邮件中的图像

问题描述

在 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

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

问题一:

有没有一种轨道方法可以像这样附加一个blob?

我可以改用以下内容:

@asset_discrepancy.images.each_with_index do |img,i|
  attachments["img_#{ i }"] = img.blob.download
end

问题二:

下载方法可以使用 RAM 的日志,这种用法不建议吗?

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

标签: ruby-on-rails-5actionmailerrails-activestorage

解决方案


在 app/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

在邮件视图中:

if @filename
  image_tag(attachments[@filename].url)
else
  image_tag(attachments['placeholder.png'].url)
end

推荐阅读