Override the default ActionMailer by a method called inside any mailer

Considering we have a custom set of headers in application.rb as

config.action_mailer.default_options = { 'X-MyCustomHeader' => "Default_value" }

I would like to be able to call a method, for example remove_custom_header

, from within any mailer and it has the header removed, or at least set to zero.

Since its custom header (starting with X-) ActionMailer allows you to create more than one and not overwrite it as you would with standard headers.

What is the best way to define a method that can overcome it?

The problem is when you call headers['X-MyCustomHeader'] = nil

inside the mailer method, it won't override it, it just creates a second header where the entry is zero, leaving the original from application.rb via email.

The only way you can override the default set is to call it default 'X-MyCustomHeader' => nil

inside ApplicationMailer (or any inherited mail server class) as shown below, but not in a method.

    class ApplicatioMailer < ActionMailer::Base
       helper :application
       default 'X-MyCustomHeader' => nil
     end

      

but I would like to call this based on the method and not in the mailer class itself as the application has many mailbox classes and they need to disable this for one or two methods in some mail servers.

My current solution:

      class ApplicatioMailer < ActionMailer::Base
        helper :application
        default 'X-MyCustomHeader' => Proc.new { @is_disabled ? nil : Rails.config.action_mailer.default_header }

        def remove_custom_header
          @is_disabled = true
        end
      end

      

and this seems to work as you are using the call default

from ActionMailer to override. Now I've tested this and it works with multiple calls, so the value @is_disabled

doesn't seem to persist between calls to the mailer. I don't understand how the var class works here in the mailer superclass that calls it and when no new class object is created, but it seems to be null every new ApplicationMailer call, so it works for me. However, is this a good solution? Am I missing something obvious? I don't feel compatible using the var class in this situation, but I can think of something else!

Thanks in advance for your help!

EDIT :: For example, I would like to call my mailers, like ...

    class MyMailer < ApplicatioMailer
      def mail_method_one(email)
        # my call
        remove_custom_header
        mail from: a.format, subject: email.subject
      end
    end

      

And if my method above setting the var class is valid and sane (which I doubt in some way), someone can explain why, as I'll be wondering how it works and will have to justify it to the lead developer! :)

+3


source to share


1 answer


Unlike what it looks like, @is_disabled

it is not a class variable, it is an instance variable. Just like a method you defined is defined as an instance class

Please note what you are doing ...

def mail_method_one(email)

      

... not...

def self.mail_method_one(email)

      

You can confirm this yourself by stopping the execution with a gem pry

or other verification tool ...



def mail_method_one(email)
  binding.pry

      

And if you look self

, you will see that you are in an instance of the mailer.

You call it as a class method, but that is because the action mailer uses the method_missing method to check if the missing class method is actually an instance method and creates a new MessageDelivery instance passing the class name, method name and arguments, and then calls the method on an instance of the mailer class.

Here's the code where it does it ...

  def method_missing(method_name, *args)
    if action_methods.include?(method_name.to_s)
      MessageDelivery.new(self, method_name, *args)
    else
      super
    end
  end

      

You can check the code here ... https://github.com/rails/rails/blob/master/actionmailer/lib/action_mailer/base.rb

+2


source







All Articles