Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow mail rendering at delay time #672

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
allow mail rendering at delay time
The current solution to delayed mail delivery renders the mail template at delivery time:
    Notifier.delay.signup(@user)

When you try to explicitly delay delivery you will get an error:
    Notifier.signup(@user).delay.deliver
    > Use MyMailer.delay.mailer_action(args) to delay sending of emails.

The new approach will serialize the mail message at delay time using Mail::Message.encoded and deserialize using the constructor:
    Notifier.signup(@user).delay.deliver
  • Loading branch information
hqm42 committed Jul 17, 2014
commit 4f7ee8f00c3cb3cc785b92a93c7bdbf78f1afbd3
15 changes: 15 additions & 0 deletions lib/delayed/performable_mail.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
require 'mail'

module Delayed
class PerformableMail < PerformableMethod
def initialize(raw_mail, method_name, args)
super(Mail.new(raw_mail), method_name, args)
end
end

module DelayMailMessage
def delay(options = {})
DelayProxy.new(PerformableMail, encoded, options)
end
end
end
6 changes: 0 additions & 6 deletions lib/delayed/performable_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,3 @@ def delay(options = {})
end
end
end

Mail::Message.class_eval do
def delay(*_args)
fail 'Use MyMailer.delay.mailer_action(args) to delay sending of emails.'
end
end
5 changes: 5 additions & 0 deletions lib/delayed/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ module Delayed
class Railtie < Rails::Railtie
initializer :after_initialize do
ActiveSupport.on_load(:action_mailer) do
module Mail
class Message
include(Delayed::DelayMailMessage)
end
end
ActionMailer::Base.extend(Delayed::DelayMail)
end
end
Expand Down
1 change: 1 addition & 0 deletions lib/delayed_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

if defined?(ActionMailer)
require 'action_mailer/version'
require 'delayed/performable_mail'
require 'delayed/performable_mailer'
end

Expand Down
6 changes: 6 additions & 0 deletions spec/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
require 'logger'
require 'rspec'

require 'mail'
require 'action_mailer'
require 'active_support/dependencies'
require 'active_record'
Expand All @@ -30,6 +31,11 @@
ActiveSupport::Dependencies.autoload_paths << File.dirname(__FILE__)

# Add this to simulate Railtie initializer being executed
module Mail
class Message
include(Delayed::DelayMailMessage)
end
end
ActionMailer::Base.extend(Delayed::DelayMail)

# Used to test interactions between DJ and an ORM
Expand Down
8 changes: 5 additions & 3 deletions spec/performable_mailer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ def signup(email)
end

describe 'delay on a mail object' do
it 'raises an exception' do
it 'delays the mail object' do
expect do
MyMailer.signup('[email protected]').delay
end.to raise_error(RuntimeError)
job = MyMailer.signup('[email protected]').delay.deliver
expect(job.payload_object.class).to eq(Delayed::PerformableMail)
expect(job.payload_object.method_name).to eq(:deliver)
end.to change { Delayed::Job.count }.by(1)
end
end

Expand Down