我在reports_controller.rb中有这个方法,它允许用户发送状态。
def send_status
date = Date.today
reports = current_user.reports.for_date(date)
ReportMailer.status_email(current_user, reports, date).deliver
head :ok
rescue => e
head :bad_request
end
如何从ActiveAdmin调用此操作,以检查用户是否发送了此报告?我希望它像列上的status_tag或其他东西。 我应该采取会员行动吗?
谢谢!
答案 0 :(得分:2)
我将解决检查报告是否稍后发送的问题,但首先我将讨论如何从ActiveAdmin调用控制器操作的问题。
虽然您可以通过创建ReportsController#send_status
然后调用所需的方法来呼叫ActionController::Base::ReportsController
,例如
ActionController::Base::ReportsController.new.send_status
这不是一个好主意。你可能应该重构这个来解决一些潜在的问题。
app/controllers/reports_controller.rb
:
class ReportsController < ApplicationController
... # rest of controller methods
def send_status
if current_user # or whatever your conditional is
ReportMailer.status_email(current_user).deliver
response = :ok
else
response = :bad_request
end
head response
end
end
app/models/user.rb
:
class User < ActiveRecord::Base
... # rest of user model
def reports_for_date(date)
reports.for_date(date)
end
end
app/mailers/reports_mailer.rb
class ReportsMailer < ActionMailer::Base
... # rest of mailer
def status_email(user)
@user = user
@date = Date.today
@reports = @user.reports_for_date(@date)
... # rest of method
end
end
这显然可以进一步重构,但提供了一个不错的起点。
需要考虑的一件重要事情是此控制器操作不是异步发送电子邮件,因此为了并发和用户体验,您应该强烈考虑使用排队系统。使用我提供的示例,DelayedJob将是一个简单的实现(查看DelayedJob RailsCast)。
至于检查报告是否已发送,您可以实现ActionMailer Observer并注册该观察者:
这要求User
模型具有BOOLEAN列status_sent
并且用户具有唯一的电子邮件地址。
lib/status_sent_mail_observer.rb
:
class StatusSentMailObserver
self.delivered_email(message)
user = User.find_by_email(message.to)
user.update_attribute(:status_sent, true)
end
end
config/intializer/setup_mail.rb
:
... # rest of initializer
Mail.register_observer(StatusSentMailObserver)
如果您正在使用DelayedJob(或几乎任何其他排队系统),您可以实现一个回调方法,以便在作业完成时调用(即发送状态电子邮件),以更新用户的列。
如果您想跟踪每天的状态消息,则应考虑创建属于Status
的{{1}}模型。每次用户发送电子邮件时都可以创建状态模型,只需检查状态记录是否存在,即可检查电子邮件是否已发送。这个策略是我认真考虑采用的一个简单的User
列。
tl; dr status_sent
&amp;实现一个观察者,用于更新跟踪状态的用户列。但你真的不想这样做。看看我上面提到过的重构。