[英]ActionMailer::Base.mail method is 'Not available' when called from initializer
[英]Rails 4/5 Sending Dynamic ActionMailer::Base.mail email With Attachment labeled 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.