jpw*_*ynn 22 ruby-on-rails actionmailer
在我的邮件控制器中,在某些条件下(缺少数据),我们中止发送电子邮件.
在这种情况下如何在不渲染视图的情况下退出控制器方法?
如果@ some_email_data.nil返回?
没有做到这一点,因为视图仍然呈现(在我尝试使用@some_email_data的每个地方抛出一个错误,除非我添加了大量的nil检查)
即使我做了零检查,它也会抱怨没有"发送者"(因为我认为在进入我设置发送者和主题的行之前做了'返回'.
也没有 render ... return
基本上,RETURN不会在邮件方法内返回!
Boz*_*sov 26
比接受的答案更简单的解决方案是:
class SomeMailer < ActionMailer::Base
def some_method
if @some_email_data.nil?
self.message.perform_deliveries = false
else
mail(...)
end
end
end
Run Code Online (Sandbox Code Playgroud)
如果您正在使用Rails 3.2.9(或更好的事情) - 那么您最终可以有条件地打电话mail().这是相关的GitHub线程.现在代码可以像这样重做:
class SomeMailer < ActionMailer::Base
def some_method
unless @some_email_data.nil?
mail(...)
end
end
end
Run Code Online (Sandbox Code Playgroud)
小智 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
Run Code Online (Sandbox Code Playgroud)
使用这些包装邮件将如下所示:
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
Run Code Online (Sandbox Code Playgroud)
它也发布在我的博客中.
我发现这种方法似乎是侵入性最小的,因为它适用于所有邮件程序方法,而不需要您记住捕获错误。在我们的例子中,我们只需要一个设置来完全禁用某些环境的邮件程序。在 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
Run Code Online (Sandbox Code Playgroud)
空的 lambda 导致 Rails 6 仅返回一个ActionMailer::Base::NullMail实例,该实例不会被传递(就像您的邮件程序方法没有调用mail或过早返回一样)。