Rails 4/5发送动态ActionMailer :: Base.mail电子邮件附件标记为Noname [英] 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>您的数据就绪< / 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如果电子邮件
结束
我可以在日志中看到它发送的内容,但假设它作为Noname发送,因为它找不到视图。任何方式让它成功工作?
以下是示例输出:
发送邮件到sample@sample.com(383.9ms)日期:
星期三,十月13日08:47:30 -0400从:样品到:
收件人消息ID:
< 57ff326270f15_421f1173954919e2@ulinux.mail>主题:样本文件
Mime版本:1.0 Content-Type:multipart / mixed; charset = UTF-8
Content-Transfer-Encoding:7bit
- 内容类型:application / vnd.openxmlformats-officedocument.spreadsheetml.sheet;
filename = 20161012T08101476259208_Data.xlsx
Content-Transfer-Encoding:base64 Content-Disposition:attachment;
filename = 20161012T08101476259208_Data.xlsx Content-ID:
< 57ff326270f15_421f1173954919e2@ulinux.mail>
UEDBBQAAAAIAO .. ... ... ADUFQAAAAA =
更新 - 我注意到如果我使用email.content_type ='text / plain'成功通过。对于我来说,这是有用的,虽然后来可以使用HTML来形容我的电子邮件,但我很欣赏。
我认为这是有效的,因为它阻止了Rails从它的通常的清理/自动解释过程。我一定想看到一个多部分/混合或html兼容的版本在这里工作。
更新2 这仅仅是人为地修复了问题宝石,它将电子邮件呈现在开发中的新选项卡上。 rails_email_preview
在生产中,这个简单可以理解的打印细节和大概是base64编码的文件,所以问题保持开放。
我有遇到这个问题,经过一番调查,似乎在Rails 4中,调用邮件方法后,您无法调用附件方法,否则邮件对象的content_type将被赢取没有边界信息,所以附件部分无法在收到的电子邮件中正确解析。
我想挖掘actionmailer的源代码,你应该能够找到一个解决方案,通过覆盖默认的邮件方法或设置正确的边界信息手动。
但是为了快速解决这个问题,我想到了一个不太优雅的工作:使用元编程:定义一个继承ActionMailer :: Base的委托类。
class AnyMailer< ActionMailer :: Base
#一个用于评估动态邮件操作的委托邮件类
end
def send_email(connection,files)
AnyMailer.class_eval do
def any_mailer(连接,文件)
files.each do | file |
report_file_name =:foo
file_location =:bar
附件[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>您的数据就绪< / p>)
end
end
AnyMailer.any_mailer(连接,文件).deliver_now
注意,您不需要将content_type指定为multipart / mixed,ActionMailer将会妥善处理。我试图明确地指定它,而是搞砸电子邮件内容。
I've taken a look at similar posts that mostly deal with sending an attachment by creating a view and controller, such as:
PDF attachment in email is called 'Noname'
but I've got a process that generates files in the background dynamically and need to attach it to a recipient list using ActionMailer::Base.mail. Below is the code:
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
I can see in the logs that it's sending with the content but assume it's sending as Noname because it can't find the view. Any way to get this to work successfully?
Below is the sample output:
Sent mail to sample@sample.com (383.9ms) Date:
Thu, 13 Oct 2016 08:47:30 -0400 From: Sample To:
Recipient Message-ID:
<57ff326270f15_421f1173954919e2@ulinux.mail> Subject: Sample File
Mime-Version: 1.0 Content-Type: multipart/mixed; charset=UTF-8
Content-Transfer-Encoding: 7bit
-- Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;
filename=20161012T08101476259208_Data.xlsx
Content-Transfer-Encoding: base64 Content-Disposition: attachment;
filename=20161012T08101476259208_Data.xlsx Content-ID:
<57ff326270f15_421f1173954919e2@ulinux.mail>
UEsDBBQAAAAIAO.. ... ...ADUFQAAAAA=
Update - I noticed if I use email.content_type = 'text/plain' - the attachment comes through successfully. For me, this works, though I'd appreciate later being able to style my emails with HTML
I presume this works because it prevents Rails from its usual gleaning/autointerpreting process. I'd certainly like to see a multipart/mixed or html compatible version work here though.
Update 2 This only fixed the issue artificially in the rails_email_preview
gem, which renders the emails to a new tab in development. In production, this simply and understandably prints the details and the presumably base64-encoded file, so question remains open.
解决方案 I have meet this problem too, after some investigation, it seems in Rails 4, you can't call attachments method after calling mail method, otherwise the content_type of the mail message object won't have boundary information so that the attachments part can't be parsed correctly in the received email.
I think digging into the actionmailer source code and you should be able to find a solution, either by override the default mail method or set the correct boundary info manually.
But for quick resolving this problem, I thought out a not elegant work around by using meta programming: define a delegation class which inherits ActionMailer::Base.
class AnyMailer < ActionMailer::Base
# a delegation mailer class used to eval dynamic mail action
end
Then eval this class with defining an arbitrary method to perform the email sending.
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
Attention, you don't need to specify the content_type as 'multipart/mixed', ActionMailer will handle it correctly. I tried to specify it explicitly but get messed up email content instead.
这篇关于Rails 4/5发送动态ActionMailer :: Base.mail电子邮件附件标记为Noname的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!