Rails5 如何每月发送电子邮件报告?
Rails5 How to deliver email reports each month?
我正在尝试设计一个报告系统,通知管理员有关客户服务应用程序的用户消息发送率和响应时间。
我有一个租户 class 看起来像这样:
class Tenant < ApplicationRecord
has_many :users
has_many :chat_messages
end
还有一个用户 class 看起来像这样:
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 这样的:
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 任务?
我认为您需要解决两件事:一种运行 定期获取所需代码的方法,以及您需要找到放置代码的地方。
CRON 长期以来一直是定期启动和 运行ning 任务的默认设置。 whenever
gem is a well-known and simple solution to manage CRON when deploying the application on common environments. Unless you are on an environment that doesn't support CRON or favors a different solution (Heroku, for example, prefers 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
这避免了依赖另一个 gem,例如 sidekiq
,并允许在您的应用程序中包含代码(而不是作为外部 rake 任务)。在您的应用程序中包含代码可以更轻松地测试和维护代码。
我正在尝试设计一个报告系统,通知管理员有关客户服务应用程序的用户消息发送率和响应时间。
我有一个租户 class 看起来像这样:
class Tenant < ApplicationRecord
has_many :users
has_many :chat_messages
end
还有一个用户 class 看起来像这样:
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 这样的:
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 任务?
我认为您需要解决两件事:一种运行 定期获取所需代码的方法,以及您需要找到放置代码的地方。
CRON 长期以来一直是定期启动和 运行ning 任务的默认设置。 whenever
gem is a well-known and simple solution to manage CRON when deploying the application on common environments. Unless you are on an environment that doesn't support CRON or favors a different solution (Heroku, for example, prefers 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
这避免了依赖另一个 gem,例如 sidekiq
,并允许在您的应用程序中包含代码(而不是作为外部 rake 任务)。在您的应用程序中包含代码可以更轻松地测试和维护代码。