2010-12-12 5 views
1

私は、ユーザーがワークアウトを追跡できるRuby on Railsアプリケーションを作成しました。個人的にも公的にもそうすることができます。公開されているトレーニング(workout.share == 1)では、ユーザーのコメントを許可します。ワークアウトにコメントが作成されると、ワークアウトの所有者に電子メールで通知されます。それはすべて素晴らしいです。アソシエーションに基づいて複数のユーザーに電子メールを送信する方法に関するアドバイス

私は現在、エクササイズにコメントしたユーザーにメールで通知するための最良の方法についていくつかのアドバイスを探しています。ここに例があります。

ユーザAがワークアウト1を作成します。ワークアウト1にユーザBのコメントがあり、ユーザAが電子メール通知を受け取ります。ユーザーCもワークアウト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} <#{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 

答えて

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. は、電子メールの送信の仕事を入れて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 
    

    に続いて次の2つの引数を持つあなたに#deliver_comment_notification_mail!メソッドをリファクタリングする必要があります。ジョブrefの遅延

:私のPOVからhttps://github.com/tobi/delayed_job

+0

ので、これは私が理解することができたものから感覚のログを作るように見えます。 2つの質問。 'commenters'はどこに定義されていますか?二つのメソッドは' deliver_comment_notificaiton_mail 'のために何でしょうか? – bgadoci

+0

私のあいまいな答えには申し訳ありません。 'commenters'メソッドは' Workout'モデルで定義されたインスタンスメソッドです。 'deliver_comment_notification_mail! 'の2つの引数は、コメントオブジェクトとユーザオブジェクトでなければなりません。別の方法として、ワークアウトの所有者とコメント作成者にメールが異なる場合は、複数の受信者またはBCCを使用してookの回答を適用し、単一のユーザーオブジェクトではなくユーザーの配列を渡すことができます。 – Kevin

0

を、それがメーラーのすべての作業です。私はcomment_notification_mailをよりニュートラルなもの(ワークアウトのオーナーやコメント作成者に話すことができる)に書き直しています。

はその後のようなもの:メールは、公開することになっていない場合は、BCCでお送りもちろん

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 

;)OK

+0

'recs'配列に重複したユーザがないことを忘れないでください。また、 'recs.inject( ''){| acc、r | "#{r.username} <#{r.email}>"} 'は最後のユーザーのみを返します。私は 'recs.map {| r | "#{r.username} <#{r.email}>"} .join( '、') '。 – tjwallace

関連する問題