【问题标题】:Rails5 How to deliver email reports each month?Rails5 如何每月发送电子邮件报告?
【发布时间】:2019-06-18 21:46:36
【问题描述】:

我正在尝试设计一个报告系统,通知管理员有关客户服务应用的用户消息传递率和响应时间。

我有一个如下所示的租户类:

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

现在我们必须手动运行 rake 任务来处理业务。 但是自动化这个过程会好得多。

所以设计了一个这样的 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

但是,我很难设置时间表我找到了this example 但我相信这样做会很快失控。我也想知道,最好的方法是什么?执行后台作业还是 rake 任务?

【问题讨论】:

  • 由于它是您所描述的计划作业,我会使用无论何时 gem 或自己添加 cron 作业。 cronjob 可以为你运行 rake 任务。
  • 那么将其作为 rake 任务是否值得?我应该开个课来处理吗?
  • 我总是推荐 Sidekiq 用于异步作业处理,但根据您的需要,这可能是矫枉过正。
  • 你说的失控是什么意思?我正在使用 sidekiq & whenever,我认为这对夫妇还可以
  • whenever 支持通过命令whenever --load-file config/my_schedule.rb 和whenever --update-crontab 手动运行不同的计划文件。所以,你可以组织你的调度器

标签: ruby-on-rails whenever rails-activejob


【解决方案1】:

我认为您需要解决两件事:一种在常规基础上运行所需代码的方法,并且您需要找到放置代码的地方。

长期以来,CRON 一直是定期启动和运行任务的默认设置。 whenever gem 是在常见环境中部署应用程序时管理 CRON 的著名且简单的解决方案。除非您所在的环境不支持 CRON 或喜欢不同的解决方案(例如 Heroku,更喜欢 Scheduler),否则我会随时选择 CRON。

关于代码的放置位置,我认为不需要像sidekiq 这样的后台处理工具,因为通过 CRON 运行代码已经是某种后台处理。此外,我认为在 rake 任务中实现这一点没有任何好处。 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 这样的其他 gem,并允许在您的应用程序中包含代码(而不是作为外部 rake 任务)。将代码放入您的应用程序可以更轻松地测试和维护代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-18
    • 2017-06-17
    • 2012-05-07
    • 2019-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多