我看了一下类似的帖子,主要是通过创建视图和控制器来处理发送附件,例如:
电子邮件中的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)2016年10月13日星期四08:47:30 -0400从:样品到:接收方问题:<57ff326270f15_421f1173954919e2@ulinux.mail>主题:示例文件Mime-Version: 1.0 Content-Type: multipart/mixed;utf - 8字符集=Content-Transfer-Encoding: 7位
——Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;文件名= 20161012 t08101476259208_data.xlsxContent-Transfer-Encoding: base64 Content-Disposition:附件;文件名= 20161012 t08101476259208_data.xlsx内容识别:& lt; 57 ff326270f15_421f1173954919e2@ulinux.mail>
UEsDBBQAAAAIAO.. ... ...ADUFQAAAAA=
更新 -我注意到如果我使用电子邮件。Content_type = 'text/plain' -附件成功通过。对我来说,这是有效的,尽管我希望以后能够使用HTML
来设置我的电子邮件的样式。我认为这是有效的,因为它阻止了Rails通常的收集/自动解释过程。我当然希望看到一个多部分/混合或html兼容的版本在这里工作。
Update 2这只在rails_email_preview
gem中人为地修复了这个问题,它将电子邮件呈现到开发中的新选项卡。在生产中,这简单且容易理解地打印细节和可能是base64编码的文件,因此问题仍然没有解决。
我也遇到过这个问题,经过一些调查,似乎在Rails 4中,在调用mail方法后,您不能调用attachments方法,否则邮件消息对象的content_type将没有边界信息,因此附件部分无法在收到的电子邮件中正确解析。
我认为挖掘到actionmailer源代码,你应该能够找到一个解决方案,要么覆盖默认的mail方法或手动设置正确的边界信息。
但是为了快速解决这个问题,我想到了一个不太优雅的工作,通过使用元编程:定义一个继承ActionMailer::Base的委托类。
class AnyMailer < ActionMailer::Base
# a delegation mailer class used to eval dynamic mail action
end
然后定义一个任意的方法来执行电子邮件发送,从而对这个类进行eval。
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模板。
其中任何一个的最小错误都将使整个电子邮件作为一个未命名的附件。
您可能没有mail .text.erb文件和mail .html.erb文件。添加它,你的邮件将是多部分的