Как выполнить возврат из ActionMailer:: базовой функции?

#ruby-on-rails #actionmailer

#ruby-on-rails #actionmailer

Вопрос:

Я пытаюсь реализовать функцию ActionMailer, которая будет рассылать новостную рассылку определенному пользователю. Я хочу убедиться, что рассылка отправляется только подписанным пользователям. Я попытался реализовать это следующим образом:

 class UserMailer < ActionMailer::Base
  def newsletter(user)
    return unless user.subscribed # This still renders my mailer view

    mail(:to => user.email, :subject => "Newsletter")
  end
end
  

Проблема в том, что return unless user.subscribed строка по-прежнему отображается в представлении почтовой программы и по-прежнему отправляется вызывающим кодом (из задания cron):

 task :cron => :environment do
  User.where(:subscribed => true).each do |user|
    UserMailer.newsletter(user).deliver
  end
end
  

Обратите внимание, что у меня также есть эта логика подписки в моем задании cron по соображениям производительности (не нужно перебирать ВСЕХ пользователей, только тех, которые подписаны). Однако, похоже, что класс UserMailer является подходящим местом для существования этой логики (в противном случае любое другое место, которое вызывает newsletter метод, также должно будет проверять subscribed флаг.

Ответ №1:

Почтовая программа, ИМХО, не подходит для этой логики. Почтовая программа не должна ничего делать, кроме форматирования и отправки сообщений. Логика для принятия решения о том, отправлять или нет, должна находиться в вызывающем блоке кода. Это неправильный способ, но что-то такое простое, как:

 UserMailer.newsletter(user).deliver if user.subscribed?
  

С другой стороны, как вы упомянули, вам не нужно перебирать всех пользователей, только подписанных. Итак, с scope в User модели, вызываемой subscribed :

 User.subscribed.each do |user|
  UserMailer.newsletter(user).deliver
end
  

Таким образом, вам не нужно тестировать для каждого пользователя; включаются только подписанные пользователи, а логика находится в вызывающем блоке, а не в почтовой программе.