在我的邮件控制器中,在某些情况下(缺少数据),我们会中止发送电子邮件。
在这种情况下如何在不渲染视图的情况下退出控制器方法?
返回@ some_email_data.nil?
由于视图仍然呈现,所以没有做到这一点(每次尝试使用@some_email_data都会抛出错误,除非我添加了大量的nil检查)
即使我做了零检查,它也会抱怨没有“发送者”(因为在我设置发件人和主题的行之前,我应该先做'返回'。
render ... return
基本上,RETURN不会在邮件程序中返回!
答案 0 :(得分:26)
比接受的答案更简单的解决方案是:
class SomeMailer < ActionMailer::Base
def some_method
if @some_email_data.nil?
self.message.perform_deliveries = false
else
mail(...)
end
end
end
如果您正在使用Rails 3.2.9(或更晚的事情) - 那么您最终可以有条件地呼叫mail()
。这是相关的GitHub thread。现在代码可以像这样重做:
class SomeMailer < ActionMailer::Base
def some_method
unless @some_email_data.nil?
mail(...)
end
end
end
答案 1 :(得分:18)
我刚刚遇到同样的事情。
我的解决方案如下:
module BulletproofMailer
class BlackholeMailMessage < Mail::Message
def self.deliver
false
end
end
class AbortDeliveryError < StandardError
end
class Base < ActionMailer::Base
def abort_delivery
raise AbortDeliveryError
end
def process(*args)
begin
super *args
rescue AbortDeliveryError
self.message = BulletproofMailer::BlackholeMailMessage
end
end
end
end
使用这些包装邮件将如下所示:
class EventMailer < BulletproofMailer::Base
include Resque::Mailer
def event_created(event_id)
begin
@event = CalendarEvent.find(event_id)
rescue ActiveRecord::RecordNotFound
abort_delivery
end
end
end
我的博客中也是posted。
答案 2 :(得分:2)
我发现此方法似乎是侵入性最小的方法,因为它适用于所有邮件方法,而无需您记住捕获错误。在我们的情况下,我们只希望针对某些环境完全禁用邮件程序的设置。在Rails 6中进行了测试,尽管我确信它也可以在Rails 5中正常工作,甚至可能更低。
class ApplicationMailer < ActionMailer::Base
class AbortDeliveryError < StandardError; end
before_action :ensure_notifications_enabled
rescue_from AbortDeliveryError, with: -> {}
def ensure_notifications_enabled
raise AbortDeliveryError.new unless <your_condition>
end
...
end
空的lambda导致Rails 6仅返回一个ActionMailer::Base::NullMail
实例,该实例不会被传递(就像您的邮递员方法没有调用mail
或过早返回一样)。
答案 3 :(得分:0)
设置self.message.perform_deliveries = false
对我不起作用。
我使用了与其他一些答案类似的方法-使用错误处理来控制流量并阻止邮件的发送。
下面的示例正在中止邮件从非生产ENV发送到未列入白名单的电子邮件,但是辅助方法逻辑可以满足您的方案需要。
class BaseMailer < ActionMailer::Base
class AbortedMailer < StandardError; end
def mail(**args)
whitelist_mail_delivery(args[:to])
super(args)
rescue AbortedMailer
Rails.logger.info "Mail aborted! We do not send emails to external email accounts outside of Production ENV"
end
private
def whitelist_mail_delivery(to_email)
return if Rails.env.production?
raise AbortedMailer.new unless internal_email?(to_email)
end
def internal_email?(to_email)
to_email.include?('@widgetbusiness.com')
end
end
答案 4 :(得分:-2)
我只是清除@to字段并返回,所以当它没有任何东西时提供中止。 (或者在设置@to之前返回)。
答案 5 :(得分:-4)
我没有花费很多时间使用rails 3,但你可以尝试使用
redirect_to some_other_route
或者,如果你真的只是检查缺失的数据,你可以对表单字段进行js验证,只有在通过时才提交。