我有一个发送电子邮件的rails代码。以下是我的控制器:
def create
@users = Users.find(:all)
@sub = params[:sub]
@body = params[:body]
@index = 0
@users.each {|i| index++; Notifier.deliver_notification(@users.email_address, @sub, @body, @users.unsubscribe_link);}
flash[:notice] = "Mail was sent to " + @index + " people"
end
我的模型中有以下内容
class Notifier < ActionMailer::Base
def notification(email, sub, content, link)
recipients email
from "my_email@example.com"
subject sub
body :content => recipient, :link => link
end
end
一切正常。我的问题是:
例如,如果向其中一个人发送邮件时出错,那么即使我的flash消息也会说。 Mail was sent to X people
如果成功发送邮件,我该怎么做才能确保@index
增加?
答案 0 :(得分:1)
deliver_notification
方法应始终返回TMail
对象,无论成功与否。有一个raise_delivery_errors
设置允许邮件程序在遇到问题时提出异常,但是你必须在你的块中拯救它们,并且只在成功时增加。
由于ActionMailer提供邮件的方式,通常情况下您不知道邮件是否成功。电子邮件通常排队并在远远超出方法调用的时间点发送,并且由于交付中的任何困难,此时大多数错误发生。它只是预先被拒绝的电子邮件地址,或者邮件传递机制不起作用。
修改:添加了例外跟踪
count = 0
@users.each do |user|
begin
Notifier.deliver_notification(
user.email_address,
@sub,
@body,
user.unsubscribe_link
)
count += 1
rescue => e
# Something went wrong, should probably store these and examine them, or
# at the very least use Rails.logger
end
end
flash[:notice] = "Mail was sent to #{count} people"
您的示例使用了Ruby不支持的index++
。你可能想要的是index += 1
。您还直接使用@users
数组而不是单个元素。
答案 1 :(得分:1)
您可以要求ActionMailer为您抛出异常,然后仅计算那些不会导致异常的交付。
ActionMailer::Base.raise_delivery_errors = true
@users.each do |i|
begin
Notifier.deliver_notification(@users.email_address, @sub, @body, @users.unsubscribe_link)
index++
rescue Exception => e
# Do whatever you want with the failed deliveries here
end
end