如何从 ActionMailer::Base 函数返回?
我正在尝试实现一个 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 except user.subscribed
行似乎仍然呈现邮件程序视图,并且仍然由调用代码(来自 cron 作业)发送:
task :cron => :environment do
User.where(:subscribed => true).each do |user|
UserMailer.newsletter(user).deliver
end
end
请注意出于性能原因,我的 cron 作业中也有该订阅逻辑(不必迭代所有用户,只需迭代那些已订阅的用户)。但是,感觉 UserMailer 类是此逻辑存在的正确位置(否则调用 newsletter
方法的任何其他位置也需要检查 subscribed
标志。
I'm trying to implement an ActionMailer function that will send out a newsletter to a specific user. I want to make sure that the newsletter is only sent to subscribed users. I tried implementing it like so:
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
The problem is that the return unless user.subscribed
line still appears to be rendering the mailer view and is still sent by the calling code (from a cron job):
task :cron => :environment do
User.where(:subscribed => true).each do |user|
UserMailer.newsletter(user).deliver
end
end
Note that I do have that subscription logic in my cron job as well for performance reasons (shouldn't have to iterate over ALL users, only those that are subscribed). However, it feels like the UserMailer class is the right place for this logic to exist (otherwise any other location that calls the newsletter
method will need to check the subscribed
flag as well.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
恕我直言,邮件程序是这种逻辑的错误地方。邮件程序除了格式化和发送消息之外什么也不要做。决定是否发送的逻辑应该位于调用代码块内。这不是正确的方法,但很简单:
或者,正如您所提到的,您不必迭代所有用户,而只需迭代订阅的用户。因此,在
User
模型中使用名为subscribed
的scope
:这样您就不需要针对每个用户进行测试;仅包含订阅用户,逻辑位于调用块中,而不是邮件程序中。
The Mailer, IMHO, is the wrong place for this logic. The mailer should do nothing but format and send messages. The logic to decide whether or not to send should be within the calling block of code. It's not the right way, but something as simple as:
Alternately, as you mentioned, you shouldn't have to iterate over all users, just the subscribed. So with a
scope
in theUser
model calledsubscribed
:This way you don't need to test on a per-user basis; only the subscribed users are included, and the logic is in the calling block, not in the mailer.