繁体   English   中英

Rails 4/5 发送动态 ActionMailer::Base.mail 电子邮件,附件标记为 Noname

[英]Rails 4/5 Sending Dynamic ActionMailer::Base.mail email With Attachment labeled Noname

我查看了类似的帖子,这些帖子主要通过创建视图和控制器来处理发送附件,例如:

电子邮件中的 PDF 附件称为“Noname”

但我有一个在后台动态生成文件的进程,需要使用 ActionMailer::Base.mail 将其附加到收件人列表中。 下面是代码:

def send_email(connection)
    email = ActionMailer::Base.mail(to: connection['to'], from: connection['from'], subject: 'Sample File', body: "<p>Hello,</p><p>Your data is ready</p>", content_type: 'multipart/mixed')
    email.cc = connection['cc'] if connection['cc'].present?
    email.bcc = connection['bcc'] if connection['bcc'].present?
    @files.each do |file|
      report_file_name = "#{@start_time.strftime('%Y%M%dT%I%m%s')}_#{file[0]}.xlsx"
      file_location = "#{Rails.root}/tmp/#{report_file_name}"
      email.attachments[report_file_name] = File.open(file_location, 'rb'){|f| f.read}
    end
    email.deliver if email
  end

我可以在日志中看到它与内容一起发送,但假设它作为 Noname 发送,因为它找不到视图。 有什么方法可以让它成功运行吗?

以下是示例输出:

发送邮件到 sample@sample.com (383.9ms) 日期:Thu, 13 Oct 2016 08:47:30 -0400 From: Sample To: Recipient Message-ID: <57ff326270f15_421f1173954919e2@ulinux.mail> 主题:示例文件 Mime-Version :1.0 内容类型:多部分/混合; charset=UTF-8 内容传输编码:7bit

-- 内容类型:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; 文件名=20161012T08101476259208_Data.xlsx 内容传输编码:base64 内容处置:附件; 文件名=20161012T08101476259208_Data.xlsx 内容 ID:<57ff326270f15_421f1173954919e2@ulinux.mail>

UEsDBBQAAAAIAO.. ... ...ADUFQAAAAA=

更新- 我注意到如果我使用 email.content_type = 'text/plain' - 附件成功通过。 对我来说,这很有效,尽管我很高兴以后能够使用 HTML 设置我的电子邮件样式

我认为这是可行的,因为它可以防止 Rails 进行通常的收集/自动解释过程。 不过,我当然希望在这里看到一个多部分/混合或 html 兼容的版本。

更新 2这只是人为地修复了rails_email_preview gem 中的问题,它将电子邮件呈现到开发中的新选项卡。 在生产中,这简单易懂地打印了细节和大概是 base64 编码的文件,所以问题仍然存在。

我也遇到过这个问题,经过一番调查,似乎在Rails 4中,调用mail方法后不能调用附件方法,否则邮件消息对象的content_type将没有边界信息,附件部分可以t 在收到的电子邮件中被正确解析。

我认为深入研究 actionmailer 源代码,您应该能够找到解决方案,方法是覆盖默认邮件方法或手动设置正确的边界信息。

但是为了快速解决这个问题,我想出了一个使用元编程的不优雅的解决方法:定义一个继承 ActionMailer::Base 的委托类。

class AnyMailer < ActionMailer::Base
  # a delegation mailer class used to eval dynamic mail action
end

然后通过定义一个任意方法来执行电子邮件发送来评估这个类。

def send_email(connection, files)
  AnyMailer.class_eval do
    def any_mailer(connection, files)
      files.each do |file|
        report_file_name = :foo
        file_location = :bar
        attachments[report_file_name] = File.open(file_location, 'rb'){|f| f.read}
      end
      mail(to: connection['to'], from: connection['from'], subject: 'Sample File', body: "<p>Hello,</p><p>Your data is ready</p>")
    end
  end

  AnyMailer.any_mailer(connection, files).deliver_now
end

注意,您不需要将 content_type 指定为 'multipart/mixed',ActionMailer 会正确处理它。 我试图明确指定它,但反而弄乱了电子邮件内容。

这一直让我发疯。 如果您使用邮件程序视图,请确保您有一个格式良好的 .html 模板和一个 .text 模板。

其中任何一个中的最小错误都会将整个电子邮件呈现为无名附件。

您可能没有 mailer.text.erb 文件和 mailer.html.erb 文件。 添加它,您的邮件将是多部分的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM