Rails Devise Custom Mailer with Mailgun gem throws "uninitialized constant" error

I’m trying to set up a custom mailer that extends Devise’s default mailer to work with the mailgun-ruby gem. I’ve configured my production.rb with the proper mailgun settings:

config.action_mailer.delivery_method = :mailgun
config.action_mailer.mailgun_settings = {
  api_key: ENV['MAILGUN_API_KEY'],
  domain: 'mail.example.com'
}

My custom mailer looks like this:

class CustomMailer < Devise::Mailer
  require 'mailgun-ruby'
  helper :application
  include Devise::Controllers::UrlHelpers
  default template_path: 'users/mailer'

  def confirmation_instructions(record, token, opts={})
    mailgun_client = MailGun::Client.new
    email_params = {
      from: "[email protected]",
      to: record.email,
      subject: "Confirm your email address"
    }

    mailgun_client.send_message email_params
    super
  end
end

I’ve commented out the mailer configuration in devise.rb initializer, but Rails keeps throwing an error saying it can’t find MailGun as a constant under CustomMailer. What’s causing this issue?

you’re overcomplicating this. move the require statement to the top of your file - it shouldn’t be inside the class. also, double-check that mailgun-ruby is in your gemfile and bundled properly. i’ve seen this constant error when the gem doesn’t load right in production.

You’ve got a case sensitivity issue with the Mailgun constant. The mailgun-ruby gem uses Mailgun::Client, not MailGun::Client with a capital G. I hit this exact same bug when I first added Mailgun to a Rails app. Change mailgun_client = MailGun::Client.new to mailgun_client = Mailgun::Client.new and that uninitialized constant error will go away. You’ll also need to pass your API key to the constructor: Mailgun::Client.new(ENV['MAILGUN_API_KEY']). One more thing - if you’ve already configured ActionMailer to use Mailgun as the delivery method, you might not need to manually create the Mailgun client in your custom mailer. You could be sending emails twice.

You’re mixing two different ways to send emails. Since you already set config.action_mailer.delivery_method = :mailgun in production, Rails will handle the Mailgun integration automatically. Your custom mailer should just build the email content - don’t manually create Mailgun clients. Delete all that mailgun_client code and let your mailer work like any normal ActionMailer class. If you need custom email content, override the method but still call mail() at the end instead of super. The config in production.rb is enough for Rails to deliver emails through Mailgun without creating clients manually.