我正在尝试实现一个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
标志。
答案 0 :(得分:1)
Mailer,恕我直言,这个逻辑是错误的。邮件程序除了格式化和发送消息之外什么都不做。决定是否发送的逻辑应该在调用代码块内。这不是正确的方法,而是简单的事情:
UserMailer.newsletter(user).deliver if user.subscribed?
或者,如您所述,您不必迭代所有用户,只需订阅。因此,scope
模型中的User
名为subscribed
:
User.subscribed.each do |user|
UserMailer.newsletter(user).deliver
end
这样您就不需要按用户进行测试;只包括订阅的用户,逻辑在调用块中,而不在邮件程序中。