Skip to content
Browse files

Support `Mailer.deliver_foo(*args)` as a synonym for `*arg…


This makes it easy to write e.g. `Mailer.expects(:deliver_foo)` when
testing code that calls the mailer.
  • Loading branch information...
1 parent aa8918a commit 7e0cf563639bc7508da381b1b8321c7a89be1aa8 @jonleighton jonleighton committed
Showing with 15 additions and 0 deletions.
  1. +5 −0 actionmailer/
  2. +3 −0 actionmailer/lib/action_mailer/base.rb
  3. +7 −0 actionmailer/test/base_test.rb
5 actionmailer/
@@ -1,5 +1,10 @@
## Rails 4.0.0 (unreleased) ##
+* Support `Mailer.deliver_foo(*args)` as a synonym for
+ `*args).deliver`. This makes it easy to write e.g.
+ `Mailer.expects(:deliver_foo)` when testing code that calls
+ the mailer. *Jon Leighton*
* Allow delivery method options to be set per mail instance *Aditya Sanghi*
If your smtp delivery settings are dynamic,
3 actionmailer/lib/action_mailer/base.rb
@@ -142,6 +142,7 @@ module ActionMailer
# for delivery later:
# Notifier.welcome(david).deliver # sends the email
+ # Notifier.deliver_welcome(david) # synonym for the former

This is an interesting addition, considering it was deprecated in ActionMailer 3.0 - see line 108 and this post among other resources.

I don't personally care for this addition and I'm interested to hear what other opinions are on this.

@jonleighton Ruby on Rails member

Interesting. I wasn't aware of that. @josevalim wdyt about this? would you prefer it to be reverted?

@jonleighton what is your plan for this? It was added a month ago, but an ack of master shows the only place it is being used is the test that was added in this commit.

I personally agreed with the decision to remove the "magic" methods. If there was a reason to re-introduce them for some reason, one could argue that the full original API should come back.

What do you think?

@josevalim do you have any opinions on this?

@dhh Ruby on Rails member
dhh added a note

I'm -1 on this. It's imo easy enough to do Mailer.expects(:welcome) and then keep mocking from there. I don't like having two ways of doing the same thing purely to make it marginally easier to mock.

@jonleighton Ruby on Rails member
Mailer.expects(:welcome).returns(mock(deliver: true))

I think the former tells the story of what's happening much more clearly than the latter.

@dhh you have also told me that "multiple ways of doing things" is the ruby way in the past (in an entirely different conversation). so not convinced by that argument.

However, I really don't care enough to argue about it, so please revert if you feel strongly.

@dhh Ruby on Rails member
dhh added a note
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
# mail = Notifier.welcome(david) # => a Mail::Message object
# mail.deliver # sends the email
@@ -487,6 +488,8 @@ def set_payload_for_mail(payload, mail) #:nodoc:
def method_missing(method_name, *args)
if action_methods.include?(method_name.to_s), self, method_name, *args)
+ elsif method_name.to_s =~ /^deliver_(.+)$/ && action_methods.include?($1)
+ public_send($1, *args).deliver
7 actionmailer/test/base_test.rb
@@ -662,6 +662,13 @@ def welcome
assert_equal [""], DefaultFromMailer.welcome.from
+ test "Mailer.deliver_welcome calls Mailer.welcome.deliver" do
+ BaseMailer.deliveries.clear
+ BaseMailer.deliver_welcome(subject: 'omg')
+ assert_equal 1, BaseMailer.deliveries.length
+ assert_equal 'omg', BaseMailer.deliveries.first.subject
+ end
# Execute the block setting the given values and restoring old values after

0 comments on commit 7e0cf56

Please sign in to comment.
Something went wrong with that request. Please try again.