Quin
Quin

Reputation: 523

Getting 'Use MyMailer.delay.mailer_action(args) to delay sending of emails.' error

I am getting an odd error: 'Use MyMailer.delay.mailer_action(args) to delay sending of emails.' but I can seem to find out where does it come from:

app/mailers/user_notifier.rb

class UserNotifier < ActionMailer::Base
  default from: "[email protected]"

  def signup_email(user)
    @user = user
    mail(to: @user.email, subject: t("mailer.signup.subject"))
  end

  ...
end

In Console, the non-delayed one works: UserNotifier.signup_email(user).deliver

but when adding delay, error occurs:

UserNotifier.signup_email(user).delay.deliver
  Rendered user_notifier/signup_email.html.erb (0.7ms)
RuntimeError: Use MyMailer.delay.mailer_action(args) to delay sending of emails.
    from /Users/quindici/.rvm/gems/ruby-2.1.2/gems/delayed_job-4.0.6/lib/delayed/performable_mailer.rb:20:in `delay'
    from (irb):6
    from /Users/quindici/.rvm/gems/ruby-2.1.2/gems/railties-4.0.0/lib/rails/commands/console.rb:90:in `start'
    from /Users/quindici/.rvm/gems/ruby-2.1.2/gems/railties-4.0.0/lib/rails/commands/console.rb:9:in `start'
    from /Users/quindici/.rvm/gems/ruby-2.1.2/gems/railties-4.0.0/lib/rails/commands.rb:64:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'

It used to work but was broken sometimes ago. Still didn't get my head around it. Any idea would be much appreciated! Thank you.

Upvotes: 0

Views: 1072

Answers (2)

Marcos de Melo
Marcos de Melo

Reputation: 61

When you use Delayed_job you'll can access .dealy method and then you can put the action mailer method like .deliver_later to delay sending of emails.

Simply way to add delayed_job in your project:

  1. Add in your Gemfile:

    gem "delayed_job_active_record"
    gem "daemons"

Create the file "config/initializers/delayed_job_config.rb" with:

Delayed::Worker.destroy_failed_jobs = false
Delayed::Worker.sleep_delay = 60
Delayed::Worker.max_attempts = 3
Delayed::Worker.max_run_time = 5.minutes
Delayed::Worker.read_ahead = 10
Delayed::Worker.default_queue_name = 'default'
Delayed::Worker.delay_jobs = !Rails.env.test?
Delayed::Worker.raise_signal_exceptions = :term
Delayed::Worker.logger = Logger.new(File.join(Rails.root, 'log', 'delayed_job.log'))
  1. In terminal:

    $ bin/rails generate delayed_job:active_record
    $ bin/rake db:migrate
    $ bundle
    $ bin/delayed_job start

Optional to view log: tail -f log/delayed_job.log

  1. In some Mailer in your project (You can execute this in rails console):

    SomeMailer.delay.some_method

Your queue will be processed in 60 seconds. You can remove the property Delayed::Worker.sleep_delay = 60 to process immediately.

Otherwise, you can configure your application to use delayed_job like your adapter for the active jobs and process works in background. Then you need to put config.active_job.queue_adapter = :delayed_job. This mode always you send an email you don't need to use .delay, instead, you call the mailer action and .deliver_later, for example: MyMailer.your_method.deliver_later. In this mode, the active job will enqueue the email in the delayed_job.

Questions and suggestions are welcome.

Reference: https://github.com/collectiveidea/delayed_job

Upvotes: 3

jeremy.clark
jeremy.clark

Reputation: 852

I think you have it backwards:

UserNotifier.signup_email(user).delay.deliver

should be

UserNotifier.delay.signup_email(user)

Upvotes: 2

Related Questions