Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added cleaner API for delaying mailers in Rails 3

Example:
	UserMailer.delay.signup(@user)

This will enqueue a job that creates the email and calls #deliver on it.
  • Loading branch information...
commit 33be987e40a3eeccb514625d88e31cb82b0b2634 1 parent 129a5d5
@bkeepers bkeepers authored
View
7 lib/delayed/message_sending.rb
@@ -3,14 +3,15 @@
module Delayed
class DelayProxy < ActiveSupport::BasicObject
- def initialize(target, options)
+ def initialize(payload_class, target, options)
+ @payload_class = payload_class
@target = target
@options = options
end
def method_missing(method, *args)
Job.create({
- :payload_object => PerformableMethod.new(@target, method.to_sym, args),
+ :payload_object => @payload_class.new(@target, method.to_sym, args),
:priority => ::Delayed::Worker.default_priority
}.merge(@options))
end
@@ -18,7 +19,7 @@ def method_missing(method, *args)
module MessageSending
def delay(options = {})
- DelayProxy.new(self, options)
+ DelayProxy.new(PerformableMethod, self, options)
end
alias __delay__ delay
View
21 lib/delayed/performable_mailer.rb
@@ -0,0 +1,21 @@
+require 'action_mailer'
+
+module Delayed
+ class PerformableMailer < PerformableMethod
+ def perform
+ object.send(method, *args).deliver
+ end
+ end
+end
+
+ActionMailer::Base.class_eval do
+ def self.delay(options = {})
+ Delayed::DelayProxy.new(Delayed::PerformableMailer, self, options)
+ end
+end
+
+Mail::Message.class_eval do
+ def delay(*args)
+ raise RuntimeError, "Use MyMailer.delay.mailer_action(args) to delay sending of emails."
+ end
+end
View
1  lib/delayed_job.rb
@@ -2,6 +2,7 @@
require File.dirname(__FILE__) + '/delayed/message_sending'
require File.dirname(__FILE__) + '/delayed/performable_method'
+require File.dirname(__FILE__) + '/delayed/performable_mailer'
require File.dirname(__FILE__) + '/delayed/yaml_ext'
require File.dirname(__FILE__) + '/delayed/backend/base'
require File.dirname(__FILE__) + '/delayed/worker'
View
46 spec/performable_mailer_spec.rb
@@ -0,0 +1,46 @@
+require 'spec_helper'
+
+require 'action_mailer'
+class MyMailer < ActionMailer::Base
+ def signup(email)
+ mail :to => email, :subject => "Delaying Emails"
+ end
+end
+
+describe ActionMailer::Base do
+ describe "delay" do
+ it "should enqueue a PerformableEmail job" do
+ lambda {
+ job = MyMailer.delay.signup('john@example.com')
+ job.payload_object.class.should == Delayed::PerformableMailer
+ job.payload_object.method.should == :signup
+ job.payload_object.args.should == ['john@example.com']
+ }.should change { Delayed::Job.count }.by(1)
+ end
+ end
+
+ describe "delay on a mail object" do
+ it "should raise an exception" do
+ lambda {
+ MyMailer.signup('john@example.com').delay
+ }.should raise_error(RuntimeError)
+ end
+ end
+
+ describe Delayed::PerformableMailer do
+ describe "perform" do
+ before do
+ @email = mock('email', :deliver => true)
+ @mailer_class = mock('MailerClass', :signup => @email)
+ @mailer = Delayed::PerformableMailer.new(@mailer_class, :signup, ['john@example.com'])
+ end
+
+ it "should call the method and #deliver on the mailer" do
+ @mailer_class.should_receive(:signup).with('john@example.com')
+ @email.should_receive(:deliver)
+ @mailer.perform
+ end
+ end
+ end
+
+end
Please sign in to comment.
Something went wrong with that request. Please try again.