Send email asynchroniously using Sidekiq.
Create your mailer us usual:
# app/mailers/users_mailer.rb
class UsersMailer < ActionMailer::Base
def welcome_email(user_id)
@user = User.find(user_id)
mail( :to => @user.email,
:subject => "Welcome"
) do |format|
format.text
format.html
end
end
end
Views for email:
app/views/users_mailer/welcome_email.html.erb - HTML version
app/views/users_mailer/welcome_email.text.erb - TEXT version
Send email:
user = User.find(1)
mail = UsersMailer.welcome_email(user.id)
#mail.deliver_now
mail.deliver_later
Gemfile:
gem 'sidekiq'
Redis provides data storage for Sidekiq. It holds all the job data along with runtime and historical data
To make work mailer.deliver_later we need to tell ActiveJob to use Sidekiq:
# config/initializers/active_job.rb
ActiveJob::Base.queue_adapter = :sidekiq
As long as Active Job is setup to use Sidekiq we can use #deliver_later:
# config/environments/development.rb
Rails.application.configure do
...
config.active_job.queue_adapter = :sidekiq
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = { ... }
end
Read more about ActionJob and Sidekiq: https://github.com/mperham/sidekiq/wiki/Active-Job
config/sidekiq.yml:
---
:concurrency: 1
:queues:
- default
- mailers
Specify queue name for different environments:
# config/initializers/sidekiq.rb
Sidekiq.configure_server do |config|
config.redis = { url: 'redis://localhost:6379/0', namespace: "mysite_sidekiq_#{Rails.env}" }
end
Sidekiq.configure_client do |config|
config.redis = { url: 'redis://localhost:6379/0', namespace: "mysite_sidekiq_#{Rails.env}" }
end
bundle exec sidekiq --environment development -C config/sidekiq.yml
Use god for monitoring and running sidekiq automatically: https://gist.github.com/maxivak/05847dc7f558d5ef282e
Read this: https://github.com/mperham/sidekiq/wiki/Devise
test environment:
# config/environments/test.rb
Rails.application.configure do
...
spec/rails_helper.rb:
# sidekiq
require 'sidekiq/testing'
Sidekiq::Testing.fake! # by default it is fake
User Sidekiq::Worker.jobs.size to see the number of jobs in the queue.
Test that email was enqueued:
RSpec.describe "Test sending email with sidekiq", :type => :request do
it 'send email to sidekiq' do
expect{
user = User.first
mail = UsersMailer.welcome_email(user.id)
mail.deliver_later
}.to change( Sidekiq::Worker.jobs, :size).by(1)
end
end
do u know how can i skip the async email send in some situations?, for example: im using cron for some rakes that send emails daily but there i dont need to use sidekiq for it but it does anyway because of the configuration that you and i use from this tutorial