如何从ActiveAdmin调用控制器操作?
我的report_controller.rb文件中有此方法,允许用户发送状态。
I have this method in my reports_controller.rb, which allows an user to send a status.
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。
我应该执行成员操作吗?
How can I call this action from ActiveAdmin, in order to check if a User sent this report or not? I want it like a status_tag on a column or something. Should I do a member action?
谢谢!
我将解决检查报告是否稍后发送的问题,但首先我将介绍如何从ActiveAdmin调用控制器操作的问题。
I'll address the issue of checking if a report has been sent later, but first I'll cover the question of how to call the controller action from ActiveAdmin.
虽然您可以通过创建 ActionController :: Base :: ReportsController
然后调用所需的调用 ReportsController#send_status
方法,例如
While you can call ReportsController#send_status
by creating an ActionController::Base::ReportsController
and then calling the desired method, e.g.
ActionController::Base::ReportsController.new.send_status
这不是一个好主意。您可能应该重构它以解决一些潜在的问题。
this isn't a good idea. You probably should refactor this to address a couple potential issues.
app / controllers / reports_controller.rb
:> p>
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
显然可以进一步重构,但是提供了一个不错的起点。
This could obviously be refactored further, but provides a decent starting point.
要考虑的重要事项是注意此控制器操作不是异步发送电子邮件,因此出于并发性和用户体验的考虑,您应该强烈考虑使用排队系统。通过我提供的示例,可以轻松实现DelayedJob(查看DelayedJob RailsCast)。
An important thing to consider is that this controller action is not sending the email asynchronously, so in the interest of concurrency and user experience, you should strongly consider using a queuing system. DelayedJob would be an easy implementation with the example I've provided (look into the DelayedJob RailsCast).
就检查报告是否已发送而言,您可以实现一个ActionMailer观察者并注册该观察者:
As far as checking if the report has been sent, you could implement an ActionMailer Observer and register that observer:
这要求 User
模型的BOOLEAN列 status_sent ,并且用户具有唯一的电子邮件地址。
This requires that the User
model have a BOOLEAN column status_sent
and that users have unique email address.
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(或几乎任何其他排队系统),则可以实现呼叫在完成工作时要调用的back方法(即发送状态电子邮件)以更新用户的列。
If you are using DelayedJob (or almost any other queuing system) you could implement a callback method to be called on job completion (i.e. sending the status email) that updates a column on the user.
如果您想每天跟踪状态消息,则应考虑创建一个 User
的>状态模型。可以在用户每次发送电子邮件时创建状态模型,从而使您可以简单地通过检查状态记录是否存在来检查电子邮件是否已发送。我会认真考虑采用这种策略,而不仅仅是采用一个简单的 status_sent
列。
If you want to track the status message for every day, you should consider creating a Status
model that belongs to the User
. The status model could be created every time the user sends the email, allowing you to check if the email has been sent simply by checking if a status record exists. This strategy is one I would seriously consider adopting over just a simple status_sent
column.
tl; dr ActionController :: Base :: ReportsController.new.send_status
&实现一个观察者,该观察者更新跟踪状态的用户上的列。但是您真的不想这样做。像我上面提到的那样进行重构。
tl;dr ActionController::Base::ReportsController.new.send_status
& implement an observer that updates a column on the user that tracks the status. But you really don't want to do that. Look into refactoring like I've mentioned above.