Question

I use ActionMailer to send different notifications to user. I use Model callbacks for this. When I do changes as admin, I don't want any email to be sent to client.

How can I disable ActionMailer in RailsAdmin?

Actually, I'd like to provide an ability to admin to turn on/off emails.

Thanks

Was it helpful?

Solution

Triggering your mailers in the model lifecycle is not recommended IMHO. The recommended approach would be to trigger the mailers from the controller.

If you want to achieve separation of concerns in your controller and not pollute your controller code with mailer calls, you can use a combination of ActiveSupport::Notifications and controller after_filter to extract the mailer logic into its own module.

module MailerCallbacks
  module ControllerExtensions
    def self.included(base)
      base.after_filter do |controller|
        ActiveSupport::Notifications.instrument(
          "mailer_callbacks.#{controller_path}##{action_name}", controller: controller
        )
      end
    end
  end

  module Listener
    def listen_to(action, &block)
      ActiveSupport::Notifications.subscribe("mailer_callbacks.#{action}") do |*args|
        event = ActiveSupport::Notifications::Event.new(*args)
        controller = event.payload[:controller]
        controller.instance_eval(&block)
      end
    end
  end
end

Let's assume you want to refactor the following controller using our module created above:

class PostsController < ApplicationController
  def create
    @post = Post.new permitted_params

    respond_to do |format|
      if @post.save
        PostMailer.notify(@post).deliver
        format.html { redirect_to @post, notice: 'Successfully created Post' }
      else
        format.html { render action: 'new' }
      end
    end
  end
end

Take the following steps:

  1. Create an initializer to register the controller extension:

    # config/initializers/mailer_callbacks.rb
    ActiveSupport.on_load(:action_controller) do
      include MailerCallbacks::ControllerExtensions
    end
    
  2. In the same or a separate initializer, create a class and extend the Listener module to register your callbacks:

    # config/initializers/mailer_callbacks.rb
    class MailerListeners
      extend MailerCallbacks::Listener
    
      # register as many listeners as you would like here
    
      listen_to 'posts#create' do
        PostMailer.notify(@post).deliver if @post.persisted?
      end
    end
    
  3. Remove mailer code from your controller.

    class PostsController < ApplicationController
      def create
        @post = Post.new permitted_params
    
        respond_to do |format|
          if @post.save
            format.html { redirect_to @post, notice: 'Successfully created Post' }
          else
            format.html { render action: 'new' }
          end
        end
      end
    end
    

Essentially we have created an observer on the controller actions and registered our mailer callbacks with the controller instead of tying it into the model lifecycle. I personally consider this approach cleaner and easier to manage.

OTHER TIPS

You should handle it on callback method.

def call_back_name
  if is_rails_admin?
   #Do nothing
  else 
    #send mail
  end
end

Let's separate this question into 2 parts:

  1. Disable email

    Check this answer

  2. Integration with Rails Admin

    You can add it to Rails Admin Navigation part and put it into separate controller for admin mailer turn on/off. More info here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top