How can I trigger a controller action from ActiveAdmin?

I have this method in my report_controller.rb that allows the user to send 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 

How can I call this action from ActiveAdmin to check if the user has sent this report or not? I want this as a status_tag in a column or something like that. Do I have to perform a member action?

Thanks!

+4
source share
1 answer

I will consider checking the report submission later, but first I will talk about how to trigger the controller action from ActiveAdmin.

For now, you can call ReportsController#send_status by creating an ActionController::Base::ReportsController and then calling the desired method, for example

 ActionController::Base::ReportsController.new.send_status 

This is not a good idea. You should probably reorganize this to solve a couple of potential problems.

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 obviously can be reorganized further, but provides a decent starting point.

It is important to note that this controller action does not send asynchronous emails, therefore, in the interests of concurrency and user experience, you should strongly consider using a queuing system. DelayedJob will be a simple implementation with the example I provided (see DelayedJob RailsCast).

As for checking report submission, you can implement Observer ActionMailer and register this observer:

This requires the User model to have a BOOLEAN status_sent column and that users have a 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) 

If you use DelayedJob (or almost any other queuing system), you can implement a callback method that must be called at the end of the job (i.e. sending status email) that updates the user column.

If you want to track the status message for each day, you should consider creating a Status model that belongs to User . A status model can be created each time a user sends an email, allowing you to check whether the email was sent simply by checking if a status entry exists. This strategy is what I would seriously consider when moving to a simple status_sent column.

tl; dr ActionController::Base::ReportsController.new.send_status and implement an observer that updates the state tracking user column. But you really do not want to do this. Look at refactoring, as I said above.

+2
source

Source: https://habr.com/ru/post/1435012/


All Articles