Skip to content
mhfs edited this page May 17, 2012 · 14 revisions

If you use the devise gem to manage authentication, you may have noticed that it's not easy to make devise send emails using sidekiq's delay helper. Here are two options on how you can easily reroute devise mail through sidekiq without any monkeypatching.

Use devise-async

Add the gem to your Gemfile

# Gemfile
gem "devise-async"

Configure Devise to use the proxy mailer.

# config/initializers/devise.rb
config.mailer = "DeviseAsync::Proxy"

And finally tell DeviseAsync to use Sidekiq to enqueue the emails.

# config/initializers/devise_async.rb
DeviseAsync.backend = :sidekiq

Do it yourself

First, configure Devise to use the new proxy class we are about to create instead of the real devise mailer.

# config/initializers/devise.rb
Devise.setup do |config|
  # ...stuff here
  config.mailer = "DeviseBackgrounder"
  # ...more stuff here
end

Then, create a new file to hold the simple proxy class that will ensure devise mails get queued for sidekiq to send.

# lib/devise_backgrounder.rb

# Mailer proxy to send devise emails in the background
class DeviseBackgrounder

  def self.confirmation_instructions(record)
    new(:confirmation_instructions, record)
  end

  def self.reset_password_instructions(record)
    new(:reset_password_instructions, record)
  end

  def self.unlock_instructions(record)
    new(:unlock_instructions, record)
  end
  
  def initialize(method, record)
    @method, @record = method, record
  end
  
  def deliver
    # You need to hardcode the class of the Devise mailer that you
    # actually want to use. The default is Devise::Mailer.
    Devise::Mailer.delay.send(@method, @record)
  end

end

That's it! Boot your app, and devise will send mail in the background. I had some trouble with my tests where the DeviseBackgrounder would choke on mocks, so I also added this line to my spec_helper.rb.

Devise.mailer = Devise::Mailer

That removes the backgrounding proxy during tests, and made everything work again for me.

Clone this wiki locally