Rails5 Как доставлять отчеты по электронной почте каждый месяц? - PullRequest
1 голос
/ 19 июня 2019

Я пытаюсь разработать систему отчетности, которая уведомляет администраторов о частоте сообщений пользователя и времени отклика для приложения обслуживания клиентов.

У меня есть класс арендатора, который выглядит следующим образом:

class Tenant < ApplicationRecord

  has_many :users
  has_many :chat_messages

end

И пользовательский класс, который выглядит следующим образом:

class User < ApplicationRecord

  belongs_to :organization
  has_many :authored_conversations, class_name: 'Conversation', :as => :author
  has_many :chat_messages, as: :user, dependent: :nullify
  has_many :received_conversations, :as => :receiver, class_name: 'Conversation'

  def conversations
    authored_conversations + received_conversations
  end

  def response_time
    # calculate the user's average response time
  end

end

Прямо сейчас нам нужно вручную запустить грабли, чтобы заняться бизнесом.Но автоматизировать процесс было бы намного лучше.

Разработан класс ReportGenerator, подобный следующему:

class ReportGenerator

  def initialize(org_id)
    @organization = Organization.find org_id
  end

  def generate_report
    report = Report.generate(@organization)
    ReportMailer.new_report(report).deliver_later
  end

end

Я также настроил свой почтовик так:

class ReportMailer < ApplicationMailer
  default from: ENV["DEFAULT_MAILER_FROM"],
          template_path: 'mailers/chat_message_mailer'

  def new_message(report, recipient)
    @report = report
    @recipient = recipient
    @subject = "Monthly report for #{report.created_at}"
    @greeting = "Hi, #{recipient.name}"
    @body = @report.body
    mail(to: @recipient.email, subject: @subject)
  end

end

Однако, Я изо всех сил пытаюсьнастроить расписание Я нашел этот пример Но я верю, что это может очень быстро выйти из-под контроля.Я также хочу знать, Каков наилучший подход?Выполнить фоновое задание или грабли?

1 Ответ

3 голосов
/ 19 июня 2019

Я бы сказал, что вам нужно решить две вещи: способ запуска необходимого кода на регулярной основе, и вам нужно найти место, куда поместить код.

По умолчанию CRON используется длязапуск и выполнение задач на регулярной основе в течение длительного времени.А гем whenever - это хорошо известное и простое решение для управления CRON при развертывании приложения в обычных средах.Если вы не находитесь в среде, которая не поддерживает CRON или предпочитает другое решение (например, Heroku предпочитает Scheduler ), я бы просто использовал CRON и всякий раз.

Относительно того, кудапоместите код, который, по моему мнению, не нужен инструмент фоновой обработки, например sidekiq, потому что запуск вашего кода через CRON уже является некоторой обработкой в ​​фоновом режиме.Кроме того, я не вижу пользы в реализации этого в граблях.Задачи Rake сложнее протестировать, и вам все равно нужно будет запустить код приложения для запроса базы данных и отправки электронных писем.

Я бы просто использовал rails runner для вызова одного метода, который создает и отправляет все электронные письма.Возможно, что-то вроде

rails runner "ReportGenerator.create_for_all_organisations"

с вашим ReportGenerator изменилось так:

class ReportGenerator
  def self.create_for_all_organisations
    Organization.find_each { |organization| new(organization).generate_report }
  end

  def initialize(organization)
    @organization = organization
  end

  def generate_report
    report = Report.generate(@organization)
    ReportMailer.new_report(report).deliver_later
  end
end

Это позволяет избежать зависимости от другого драгоценного камня, такого как sidekiq, и позволяет иметь код в вашем приложении.(не в качестве внешней грабли).Наличие кода в вашем приложении значительно облегчает тестирование и сопровождение кода.

...