Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delay sending emails

I have the following code in an AnswerObserver < ActiveRecord::Observer in my Rails app. After an answer is created, an email is sent out to users watching the question.

  def after_create(answer)
    answer.question.watchers.each do |user|
    Notifier.answer_updated(answer, user).deliver
  end 

Notifier inherits from ActionMailer class Notifier < ActionMailer::Base and has the method

 def answer_updated(answer, user)
    @answer = answer
    @user = user
    mail(:to => user.email,
         :subject => "Your question has been answered")
  end 

I'm now trying to use SideKiq to move it to a background process. I have redis installed and running and I started sidekiq successfully with bundle exec sidekiq.

According to this blogpost http://blog.remarkablelabs.com/2013/01/using-sidekiq-to-send-emails-asynchronously, SideKiq has built in support for ActionMailer

The method that you will likely use the most is .delay. Calling .delay from an Action Mailer will result in the email being added to the DelayedMailer queue for processing.

Therefore, I replaced "deliver" method with 'delay" in the observer that calls the action mailer method answer_updated, like this

  def after_create(answer)
    answer.question.watchers.each do |user|
    Notifier.answer_updated(answer, user).delay
  end 

But now I'm getting this error

undefined method `delay' for #<Mail::Message:0x007fee0c9af1d0>

I haven't done anything else to configure SideKiq. Can you explain what I might be doing wrong?

like image 492
Tomoko Yamaguchi Avatar asked Dec 27 '22 05:12

Tomoko Yamaguchi


2 Answers

The correct way to do this is :

Notifier.delay.answer_updated(answer, user)

See the examples in the file Here

like image 191
Intrepidd Avatar answered Dec 28 '22 19:12

Intrepidd


It didn't work out for me. There is no delay method for mailer. Take a look here:

>> RUBY_VERSION
=> "2.2.0"
>> Rails::VERSION::STRING
=> "4.2.1"

>> mailer.methods.include?(:delay)
=> false
>> mailer.send_email(mailable, recipient).methods.include?(:deliver_later)
=> true

So, if you use Rails > 4.2 use this:

Notifier.answer_updated(answer, user).deliver_later
like image 29
Tomasz Jaśkiewicz Avatar answered Dec 28 '22 18:12

Tomasz Jaśkiewicz