1

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

我现在正在寻找一些建议,以让对锻炼发表评论的用户也可以通过电子邮件收到通知。这是一个例子。

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

告诉我的应用程序遍历所有评论过锻炼 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} <#{comment.workout.user.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
4

2 回答 2

1

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

  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. 使用延迟作业或其他工具将电子邮件发送作业置于后台,否则请求将被阻止,直到所有电子邮件都发送完毕。例如,在#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

于 2010-12-12T06:48:28.487 回答
0

从我的观点来看,这都是邮寄者的工作。我只是将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

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

于 2010-12-12T06:57:42.940 回答