Советы по отправке электронной почты нескольким пользователям на основе ассоциации - PullRequest
1 голос
/ 12 декабря 2010

Я создал приложение 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} <#{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

Ответы [ 2 ]

1 голос
/ 12 декабря 2010

Найти владельца и комментатора тренировки не сложно.Мои предложения:

  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! с двумя аргументами.

Задержка ref ref: https://github.com/tobi/delayed_job

0 голосов
/ 12 декабря 2010

Из моего 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

Конечно, если письма не должныбыть публичным, отправьте по bcc;)

...