我正在将Rails 2.3.14应用程序迁移到Rails 3.0。在它中,一个邮递员发送一条带有附件的信息。使用下面的代码,这在2.3.x.中没有问题
def notification(material, recipient, path_to_file)
enctype = "base64"
@recipients = recipient.email
@from = material.person.email
@reply_to = material.person.email
@subject = "New or updated materials: " + material.name
@sent_on = Time.now
@content_type = "multipart/mixed"
@headers['sender'] = material.person.email
part :content_type => "text/plain",
:body => render_message('notification',
:material => material,
:url => material.full_url_to_material)
attachment :content_type => "application" + "/" + material.file_type,
:body => File.read(path_to_file),
:filename => File.basename(material.file),
:transfer_encoding => enctype,
:charset => "utf-8" if !!material.send_as_attachment
end
通过阅读Rails 3.0 ActionMailer指令,我将该方法修改为:
def notification(material, recipient, path_to_file)
@material = material
@url = material.full_url_to_material
attachments[material.file_file_name] = File.open(path_to_file, 'rb'){|f| f.read} if material.send_as_attachment?
headers['sender'] = material.person.email
mail(:to => recipient.email,
:subject => "New or updated materials: " + material.name,
:reply_to => material.person.email,
:from => material.person.email)
end
创建材质时会调用MaterialMailer#通知。我有以下规格来测试这个:
it "will include the materials as an attachement with the the send_as_attachment field is set to 1" do
it = Material.create(@materials_hash.merge(:send_notification => "1", :send_as_attachment => "1"))
email = ActionMailer::Base.deliveries[0]
email.body.should =~ Regexp.new("Name of the posted material: " + it.name )
email.has_attachments?.should be_true
end
正如我提到的,这在2.3中运行良好。现在,如果我将send_as_attachment标志设置为1,我会得到以下错误,引用email.body.sshould行:
1) Material will include the materials as an attachement with the the send_as_attachment field is set to 1
Failure/Error: email.body.should =~ Regexp.new("Name of the posted material: " + it.name )
expected: /Name of the posted material: My material/
got: (using =~)
Diff:
@@ -1,2 +1 @@
-/Name of the posted material: My material/
如果我更改规范并将send_as_attachment设置为0,则会出现以下错误,引用has_attachments?行:
1) 材质将包含作为附件的材质,send_as_attachment字段设置为1失败/错误:电子邮件。是否有附件?。应该是true预期错误为真
因此,包含附件在某种程度上破坏了电子邮件。
我尝试过其他方法来附着材料:
attachments[material.file_file_name] = {:mime_type => "application" + "/" + material.file_content_type,
:content => File.read(material.file.path),
:charset => "utf-8"}
我已尝试将文件路径硬编码为已知文件。但运气不好。
还有其他地方我应该找吗?
根据Christopher的建议,以下是我用来让它工作的邮件和规范代码:
def notification(material, recipient, path_to_file)
@material = material
@url = material.full_url_to_material
attachments[material.file_file_name] = File.open(material.file.path, 'rb'){|f| f.read} if material.send_as_attachment?
headers['sender'] = material.person.email
mail(:to => recipient.email,
:subject => message_subject("New or updated materials: " + material.name),
:reply_to => material.person.email,
:from => material.person.email)
end
it "will include the materials as an attachment with the the send_as_attachment field is set to 1" do
it = Material.create(@materials_hash.merge(:send_notification => "1", :send_as_attachment => "1"))
Delayed::Worker.new(:quiet => true).work_off
email = ActionMailer::Base.deliveries[0]
email.parts.each.select{ |email| email.body =~ Regexp.new("Name of the posted material: " + it.name )}.should_not be_empty
email.has_attachments?.should be_true
end
在规范中,我必须检查电子邮件每个部分的正文,因为附件是第一部分还是第二部分并不一致。