Подтвердить что ты не робот

Rails 3: как отменить метод доставки в actionmailer?

В моем почтовом контроллере при определенных условиях (отсутствующих данных) мы отменяем отправку электронной почты.

Как выйти из метода контроллера, не создавая в этом случае представление?

return if @some_email_data.nil?

Не делает трюк, поскольку представление все еще отображается (бросая ошибку в каждое место, которое я пытаюсь использовать @some_email_data, если я не добавляю много проверок nil)

И даже если я делаю нулевые проверки, он жалуется, что нет "отправителя" (потому что я предположил, что сделал "возврат", прежде чем перейти к строке, где я установил отправителя и тему.

Также не существует render ... return

В принципе, RETURN НЕ ВОЗВРАЩАЕТСЯ в метод почтовой программы!

4b9b3361

Ответ 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

в качестве альтернативы, если вы действительно просто проверяете отсутствие данных, вы можете выполнить проверку правильности полей формы и только отправить, если она пройдет.