有关如何根据关联向多个用户发送电子邮件的建议

我创建了一个Ruby on Rails应用程序,用户可以在其中跟踪锻炼。 可以私下或公开地这样做。 在公开的训练中( workout.share == 1 )我允许用户发表评论。 在锻炼中创建评论时,将通过电子邮件通知锻炼所有者。 一切都很好。

我现在正在寻找一些关于允许评论锻炼的用户的最佳方式的建议,也可以通过电子邮件通知。 这是一个例子。

用户A创建锻炼1.用户B对锻炼1的评论和用户A收到电子邮件通知。 用户C还对Workout 1发表评论,用户A和用户B都接收电子邮件通知。

告诉我的应用程序循环浏览已对Workout 1发表评论并向其发送电子邮件的所有用户的最佳方法是什么?

目前,我正在使用comments_controller中的以下代码向锻炼所有者发送电子邮件(我意识到这可能是更干净的代码):

 class CommentsController < ApplicationController ... def create @workout = Workout.find(params[:workout_id]) @comment = @workout.comments.build(params[:comment]) @comment.user = current_user respond_to do |format| if @comment.save if @comment.workout.email_notification == 1 @comment.deliver_comment_notification_mail! format.html { redirect_to( projects_path) } format.js else format.html { redirect_to( projects_path) } format.js end else end end end ... 

并在comment_mailer.rb中

 def comment_notification_mail(comment) subject "Someone commented on your Workout" recipients("#{comment.workout.user.username} ") from("foobar") body :comment => comment, :commenter => comment.user, :workout => comment.workout, :commentee => comment.workout.user, :workout_url => workout_url(comment.workout), :commenter_url => user_url(comment.user) end 

找出锻炼所有者和评论者并不是一项艰苦的工作。 我的建议是:

  1. 使用#after_create将控制器中发送电子邮件的代码移动到您的模型,例如:

     class Comment < ActiveRecord::Base #... after_create :notify_subscribers def subscribers (self.workout.commenters << self.workout.owner).uniq end def notify_subscribers #... implemented below end end 
  2. 使用delayed_job或其他工具将电子邮件发送作业放到后台,或者在发送所有电子邮件之前阻止请求。 例如,在#notify_owner_and_commenter方法中

     def notify_subscribers self.subscribers.each do |user| CommentMailer.send_later :deliver_comment_notification_mail!(self, user) end end 

    然后你需要重构#deliver_comment_notification_mail! 有两个参数的方法。

延迟工作参考: https : //github.com/tobi/delayed_job

从我的POV,这是邮件的所有工作。 我只是将comment_notification_mail重写为更中性的东西(可以与锻炼所有者和评论者交谈)。

然后像:

 def comment_notification_mail(comment) recs = [comment.workout.user] recs << comment.workout.comments(&:user) recs -= comment.user subject "Someone commented on your Workout" recipients(recs.inject('') { |acc, r| "#{r.username} <#{r.email}>" }) from("foobar") body :comment => comment, :commenter => comment.user, :workout => comment.workout, :commentee => comment.workout.user, :workout_url => workout_url(comment.workout), :commenter_url => user_url(comment.user) end 

当然,如果邮件不应该公开,请通过密送发送;)