Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails + Devise + delayed_job?

I have a Rails 3 App using Devise on Heroku. Problem is I'm sending emails with Sendgrid and email delivery is slow, it makes the app hang. So I'm interested in using delayed_job to queue the email delivery in the background so my app is responsive to the user.

How can Devise be used with delayed_job? Any way to setup Devise to use delayed_job?

like image 779
AnApprentice Avatar asked Nov 08 '10 16:11

AnApprentice


6 Answers

From Robert May: https://gist.github.com/659514

Add this to a file in config/initializers directory:

module Devise
  module Models
    module Confirmable
      handle_asynchronously :send_confirmation_instructions
    end

    module Recoverable
      handle_asynchronously :send_reset_password_instructions
    end

    module Lockable
      handle_asynchronously :send_unlock_instructions
    end
  end
end
like image 125
Vee Avatar answered Nov 11 '22 23:11

Vee


According to the Devise wiki page, the devise-async gem will handle this for you. It supports delayed_job, resque, and sidekiq.

like image 12
Terry Schmidt Avatar answered Nov 11 '22 22:11

Terry Schmidt


I found that none of the above worked for me. I'm using Devise 2.0.4 and Rails 3.2.2 with delayed_job_active_record 0.3.2

The way devise actually talks about doing something like this in the comments in the code is to override the methods in the User class. Thus, I solved it like so, and it works perfectly:

app/models/User.rb

def send_on_create_confirmation_instructions
  Devise::Mailer.delay.confirmation_instructions(self)
end
def send_reset_password_instructions
  Devise::Mailer.delay.reset_password_instructions(self)
end
def send_unlock_instructions
  Devise::Mailer.delay.unlock_instructions(self)
end
like image 6
hrdwdmrbl Avatar answered Nov 11 '22 23:11

hrdwdmrbl


this is the thing that worked for me:

in app/models/user.rb

  # after your devise declarations
  handle_asynchronously :send_reset_password_instructions
  handle_asynchronously :send_confirmation_instructions
  handle_asynchronously :send_on_create_confirmation_instructions

you may not need all of them depending on which devise modules you are including

like image 3
fringd Avatar answered Nov 11 '22 21:11

fringd


I'm not sure Devise provides an easy way to do backgrounding of email delivery. However there are ways to be able to do that with DelayedJoy. DelyedJob provides a function "handle_asynchronously" which if injected into the DeviseMailer can ensure that deliveries happen in the background.

Try this in your config/application.rb

config.after_initialize do 
  ::DeviseMailer.handle_asynchronously :deliver_confirmation_instructions 
  # or
  ::DeviseMailer.handle_asynchronously :deliver!
end

You will need to experiment with that. You could also try to inherit the DeviseMailer and set it to deliver asynchronously in an initializer in config/initializer/devise_mailer_setup.rb or something to that effect.

like image 1
Aditya Sanghi Avatar answered Nov 11 '22 21:11

Aditya Sanghi


For delayed_job_active_record with Devise , just use the following . (add it to user.rb model )

handle_asynchronously :send_devise_notification, :queue => 'devise'
like image 1
Mani Avatar answered Nov 11 '22 23:11

Mani