Rails 3: как отменить метод доставки в actionmailer?
В моем почтовом контроллере при определенных условиях (отсутствующих данных) мы отменяем отправку электронной почты.
Как выйти из метода контроллера, не создавая в этом случае представление?
return if @some_email_data.nil?
Не делает трюк, поскольку представление все еще отображается (бросая ошибку в каждое место, которое я пытаюсь использовать @some_email_data, если я не добавляю много проверок nil)
И даже если я делаю нулевые проверки, он жалуется, что нет "отправителя" (потому что я предположил, что сделал "возврат", прежде чем перейти к строке, где я установил отправителя и тему.
Также не существует render ... return
В принципе, RETURN НЕ ВОЗВРАЩАЕТСЯ в метод почтовой программы!
Ответы
Ответ 1
Я только что столкнулся с этим.
Мое решение следующее:
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
В моем блоге также есть .
Ответ 2
Более простое решение, чем принятый ответ, будет примерно таким:
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. Теперь код можно переработать следующим образом:
class SomeMailer < ActionMailer::Base
def some_method
unless @some_email_data.nil?
mail(...)
end
end
end
Ответ 3
Настройка 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
Я просто очищаю поле @to и возвращаю, поэтому доставляю прерывания, когда у него ничего нет. (Или просто верните перед установкой @to).
Ответ 5
Я не потратил много времени на рельсы 3, но вы можете попробовать использовать
redirect_to some_other_route
в качестве альтернативы, если вы действительно просто проверяете отсутствие данных, вы можете выполнить проверку правильности полей формы и только отправить, если она пройдет.