Skip to content

Commit

Permalink
Merge pull request #1121 from johnnyshields/patch-3
Browse files Browse the repository at this point in the history
Make .delay method work with ActionMailer::Parameterized::Mailer
  • Loading branch information
albus522 committed Dec 9, 2020
2 parents c35dd0f + 75bec31 commit 50a0712
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 6 deletions.
17 changes: 11 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,10 @@ end

If you ever want to call a `handle_asynchronously`'d method without Delayed Job, for instance while debugging something at the console, just add `_without_delay` to the method name. For instance, if your original method was `foo`, then call `foo_without_delay`.

Rails 3 Mailers
===============
Due to how mailers are implemented in Rails 3, we had to do a little work around to get delayed_job to work.
Rails Mailers
=============
Delayed Job uses special syntax for Rails Mailers.
Do not call the `.deliver` method when using `.delay`.

```ruby
# without delayed_job
Expand All @@ -178,12 +179,16 @@ Notifier.signup(@user).deliver
# with delayed_job
Notifier.delay.signup(@user)

# with delayed_job running at a specific time
# delayed_job running at a specific time
Notifier.delay(run_at: 5.minutes.from_now).signup(@user)

# when using parameters, the .with method must be called before the .delay method
Notifier.with(foo: 1, bar: 2).delay.signup(@user)
```

Remove the `.deliver` method to make it work. It's not ideal, but it's the best
we could do for now.
You may also wish to consider using
[Active Job with Action Mailer](https://edgeguides.rubyonrails.org/active_job_basics.html#action-mailer)
which provides convenient `.deliver_later` syntax that forwards to Delayed Job under-the-hood.

Named Queues
============
Expand Down
1 change: 1 addition & 0 deletions lib/delayed_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
ActiveSupport.on_load(:action_mailer) do
require 'delayed/performable_mailer'
ActionMailer::Base.extend(Delayed::DelayMail)
ActionMailer::Parameterized::Mailer.include(Delayed::DelayMail) if defined?(ActionMailer::Parameterized::Mailer)
end

module Delayed
Expand Down
26 changes: 26 additions & 0 deletions spec/performable_mailer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,29 @@ def signup(email)
end
end
end

if defined?(ActionMailer::Parameterized::Mailer)
describe ActionMailer::Parameterized::Mailer do
describe 'delay' do
it 'enqueues a PerformableEmail job' do
expect do
job = MyMailer.with(:foo => 1, :bar => 2).delay.signup('[email protected]')
expect(job.payload_object.class).to eq(Delayed::PerformableMailer)
expect(job.payload_object.object.class).to eq(ActionMailer::Parameterized::Mailer)
expect(job.payload_object.object.instance_variable_get('@mailer')).to eq(MyMailer)
expect(job.payload_object.object.instance_variable_get('@params')).to eq(:foo => 1, :bar => 2)
expect(job.payload_object.method_name).to eq(:signup)
expect(job.payload_object.args).to eq(['[email protected]'])
end.to change { Delayed::Job.count }.by(1)
end
end

describe 'delay on a mail object' do
it 'raises an exception' do
expect do
MyMailer.with(:foo => 1, :bar => 2).signup('[email protected]').delay
end.to raise_error(RuntimeError)
end
end
end
end

0 comments on commit 50a0712

Please sign in to comment.