aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCristian Bica <cristian.bica@gmail.com>2014-08-20 15:34:37 +0300
committerCristian Bica <cristian.bica@gmail.com>2014-08-20 17:48:34 +0300
commit9e7f4a94caa9019b2ef0295ad242fbed0acf8bb6 (patch)
treec12dd82460b3d8e7b351effe4afd3b8f0e5f4cf8
parentf4ee114746ddc68db606f63e17e6de28274fc2bd (diff)
downloadrails-9e7f4a94caa9019b2ef0295ad242fbed0acf8bb6.tar.gz
rails-9e7f4a94caa9019b2ef0295ad242fbed0acf8bb6.tar.bz2
rails-9e7f4a94caa9019b2ef0295ad242fbed0acf8bb6.zip
Updated rdoc / guides / release notes related to ActiveJob / ActionMailer
-rw-r--r--actionmailer/CHANGELOG.md10
-rw-r--r--actionmailer/README.rdoc6
-rw-r--r--actionmailer/lib/action_mailer/base.rb21
-rw-r--r--actionmailer/lib/action_mailer/delivery_job.rb4
-rw-r--r--actionmailer/lib/action_mailer/message_delivery.rb89
-rw-r--r--actionmailer/lib/action_mailer/test_helper.rb12
-rw-r--r--guides/source/4_2_release_notes.md3
-rw-r--r--guides/source/action_mailer_basics.md32
-rw-r--r--guides/source/active_job_basics.md6
-rw-r--r--guides/source/active_record_querying.md10
-rw-r--r--guides/source/testing.md2
11 files changed, 141 insertions, 54 deletions
diff --git a/actionmailer/CHANGELOG.md b/actionmailer/CHANGELOG.md
index a4923de045..1ff4db41a3 100644
--- a/actionmailer/CHANGELOG.md
+++ b/actionmailer/CHANGELOG.md
@@ -1,7 +1,9 @@
-* Added #deliver_later in addition to #deliver, which will enqueue a job to render and
- deliver the mail instead of delivering it right at that moment. The job is enqueued
- using the new Active Job framework in Rails, and will use whatever queue is configured for Rails.
-
+* Added #deliver_later, #deliver_now and deprecate #deliver in favour of
+ #deliver_now. #deliver_later will enqueue a job to render and deliver
+ the mail instead of delivering it right at that moment. The job is enqueued
+ using the new Active Job framework in Rails, and will use whatever queue is
+ configured for Rails.
+
*DHH/Abdelkader Boudih/Cristian Bica*
* Make ActionMailer::Previews methods class methods. Previously they were
diff --git a/actionmailer/README.rdoc b/actionmailer/README.rdoc
index ceca912ada..3b8e3ed749 100644
--- a/actionmailer/README.rdoc
+++ b/actionmailer/README.rdoc
@@ -65,12 +65,12 @@ In order to send mails, you simply call the method and then call +deliver+ on th
Calling the method returns a Mail Message object:
- message = Notifier.welcome("david@loudthinking.com") # => Returns a Mail::Message object
- message.deliver # => delivers the email
+ message = Notifier.welcome("david@loudthinking.com") # => Returns a Mail::Message object
+ message.deliver_now # => delivers the email
Or you can just chain the methods together like:
- Notifier.welcome("david@loudthinking.com").deliver # Creates the email and sends it immediately
+ Notifier.welcome("david@loudthinking.com").deliver_now # Creates the email and sends it immediately
== Setting defaults
diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb
index 9aae14ec8c..fc2d0936f9 100644
--- a/actionmailer/lib/action_mailer/base.rb
+++ b/actionmailer/lib/action_mailer/base.rb
@@ -138,9 +138,20 @@ module ActionMailer
# Once a mailer action and template are defined, you can deliver your message or create it and save it
# for delivery later:
#
- # Notifier.welcome(david).deliver # sends the email
- # mail = Notifier.welcome(david) # => a Mail::Message object
- # mail.deliver # sends the email
+ # Notifier.welcome(david).deliver_now # sends the email
+ # mail = Notifier.welcome(david) # => an ActionMailer::MessageDeliver object
+ # mail.deliver_now # sends the email
+ #
+ # The <tt>ActionMailer::MessageDeliver</tt> class is a wrapper around a <tt>Mail::Message</tt> object. If
+ # you want direct access to the <tt>Mail::Message</tt> object you can call the <tt>message</tt> method on
+ # the <tt>ActionMailer::MessageDeliver</tt> object.
+ #
+ # Notifier.welcome(david).message # => a Mail::Message object
+ #
+ # ActionMailer is nicely integrated with ActiveJob so you can send emails in the background (example: outside
+ # of the request-response cycle, so the user doesn't have to wait on it):
+ #
+ # Notifier.welcome(david).deliver_later # enqueue the email sending to ActiveJob
#
# You never instantiate your mailer class. Rather, you just call the method you defined on the class itself.
#
@@ -322,8 +333,8 @@ module ActionMailer
# end
#
# Methods must return a <tt>Mail::Message</tt> object which can be generated by calling the mailer
- # method without the additional <tt>deliver</tt>. The location of the mailer previews
- # directory can be configured using the <tt>preview_path</tt> option which has a default
+ # method without the additional <tt>deliver_now</tt> / <tt>deliver_later</tt>. The location of the
+ # mailer previews directory can be configured using the <tt>preview_path</tt> option which has a default
# of <tt>test/mailers/previews</tt>:
#
# config.action_mailer.preview_path = "#{Rails.root}/lib/mailer_previews"
diff --git a/actionmailer/lib/action_mailer/delivery_job.rb b/actionmailer/lib/action_mailer/delivery_job.rb
index b2cfa245fd..622f202695 100644
--- a/actionmailer/lib/action_mailer/delivery_job.rb
+++ b/actionmailer/lib/action_mailer/delivery_job.rb
@@ -1,10 +1,10 @@
require 'active_job'
module ActionMailer
- class DeliveryJob < ActiveJob::Base
+ class DeliveryJob < ActiveJob::Base #:nodoc:
queue_as :mailers
- def perform(mailer, mail_method, delivery_method, *args)
+ def perform(mailer, mail_method, delivery_method, *args) #:nodoc#
mailer.constantize.public_send(mail_method, *args).send(delivery_method)
end
end
diff --git a/actionmailer/lib/action_mailer/message_delivery.rb b/actionmailer/lib/action_mailer/message_delivery.rb
index 8136483725..e65e79e741 100644
--- a/actionmailer/lib/action_mailer/message_delivery.rb
+++ b/actionmailer/lib/action_mailer/message_delivery.rb
@@ -1,65 +1,112 @@
require 'delegate'
module ActionMailer
+
+ # The ActionMailer::MessageDeliver class is used by ActionMailer::Base when
+ # creating a new mailer. MessageDeliver is a wrapper (Delegator subclass)
+ # around a lazy created Mail::Message. You can get direct access to the
+ # Mail::Message, deliver the email or schedule the email to be sent through ActiveJob.
+ #
+ # Notifier.welcome(david) # an ActionMailer::MessageDeliver object
+ # Notifier.welcome(david).deliver_now # sends the email
+ # Notifier.welcome(david).deliver_later # enqueue the deliver email job to ActiveJob
+ # Notifier.welcome(david).message # a Mail::Message object
class MessageDelivery < Delegator
- def initialize(mailer, mail_method, *args)
+ def initialize(mailer, mail_method, *args) #:nodoc:
@mailer = mailer
@mail_method = mail_method
@args = args
end
- def __getobj__
+ def __getobj__ #:nodoc:
@obj ||= @mailer.send(:new, @mail_method, *@args).message
end
- def __setobj__(obj)
+ def __setobj__(obj) #:nodoc:
@obj = obj
end
- def message #:nodoc:
+ # Returns the Mail::Message object
+ def message
__getobj__
end
+ # Enqueues the message to be delivered through ActiveJob. When the
+ # ActiveJob job runs it will send the email using #deliver_now!. That
+ # means that the message will be sent bypassing checking perform_deliveries
+ # and raise_delivery_errors, so use with caution.
+ #
+ # ==== Examples
+ #
+ # Notifier.welcome(david).deliver_later
+ # Notifier.welcome(david).deliver_later(in: 1.hour)
+ # Notifier.welcome(david).deliver_later(at: 10.hours.from_now)
+ #
+ # ==== Options
+ # * <tt>in</tt> - Enqueue the message to be delivered with a delay
+ # * <tt>at</tt> - Enqueue the message to be delivered at (after) a specific date / time
def deliver_later!(options={})
enqueue_delivery :deliver_now!, options
end
+ # Enqueues the message to be delivered through ActiveJob. When the
+ # ActiveJob job runs it will send the email using #deliver_now.
+ #
+ # ==== Examples
+ #
+ # Notifier.welcome(david).deliver_later
+ # Notifier.welcome(david).deliver_later(in: 1.hour)
+ # Notifier.welcome(david).deliver_later(at: 10.hours.from_now)
+ #
+ # ==== Options
+ # * <tt>in</tt> - Enqueue the message to be delivered with a delay
+ # * <tt>at</tt> - Enqueue the message to be delivered at (after) a specific date / time
def deliver_later(options={})
enqueue_delivery :deliver_now, options
end
+ # Delivers a message. The message will be sent bypassing checking perform_deliveries
+ # and raise_delivery_errors, so use with caution.
+ #
+ # Notifier.welcome(david).deliver_now!
+ #
def deliver_now!
message.deliver!
end
+ # Delivers a message:
+ #
+ # Notifier.welcome(david).deliver_now
+ #
def deliver_now
message.deliver
end
- def deliver!
- ActiveSupport::Deprecation.warn "#deliver! is deprecated and will be removed on Rails 5. " \
- "Use #deliver_now! to deliver immediately or #deliver_later! to deliver through ActiveJob"
+ def deliver! #:nodoc:
+ ActiveSupport::Deprecation.warn "#deliver! is deprecated and will be removed in Rails 5. " \
+ "Use #deliver_now! to deliver immediately or #deliver_later! to deliver through ActiveJob."
deliver_now!
end
- def deliver
- ActiveSupport::Deprecation.warn "#deliver is deprecated and will be removed on Rails 5. " \
- "Use #deliver_now to deliver immediately or #deliver_later to deliver through ActiveJob"
+ def deliver #:nodoc:
+ ActiveSupport::Deprecation.warn "#deliver is deprecated and will be removed in Rails 5. " \
+ "Use #deliver_now to deliver immediately or #deliver_later to deliver through ActiveJob."
deliver_now
end
private
- def enqueue_delivery(delivery_method, options={})
- args = @mailer.name, @mail_method.to_s, delivery_method.to_s, *@args
- enqueue_method = :enqueue
- if options[:at]
- enqueue_method = :enqueue_at
- args.unshift options[:at]
- elsif options[:in]
- enqueue_method = :enqueue_in
- args.unshift options[:in]
+
+ def enqueue_delivery(delivery_method, options={})
+ args = @mailer.name, @mail_method.to_s, delivery_method.to_s, *@args
+ enqueue_method = :enqueue
+ if options[:at]
+ enqueue_method = :enqueue_at
+ args.unshift options[:at]
+ elsif options[:in]
+ enqueue_method = :enqueue_in
+ args.unshift options[:in]
+ end
+ ActionMailer::DeliveryJob.send enqueue_method, *args
end
- ActionMailer::DeliveryJob.send enqueue_method, *args
- end
end
end
diff --git a/actionmailer/lib/action_mailer/test_helper.rb b/actionmailer/lib/action_mailer/test_helper.rb
index 06da0dd27e..6ddacf7b79 100644
--- a/actionmailer/lib/action_mailer/test_helper.rb
+++ b/actionmailer/lib/action_mailer/test_helper.rb
@@ -6,9 +6,9 @@ module ActionMailer
#
# def test_emails
# assert_emails 0
- # ContactMailer.welcome.deliver
+ # ContactMailer.welcome.deliver_now
# assert_emails 1
- # ContactMailer.welcome.deliver
+ # ContactMailer.welcome.deliver_now
# assert_emails 2
# end
#
@@ -17,12 +17,12 @@ module ActionMailer
#
# def test_emails_again
# assert_emails 1 do
- # ContactMailer.welcome.deliver
+ # ContactMailer.welcome.deliver_now
# end
#
# assert_emails 2 do
- # ContactMailer.welcome.deliver
- # ContactMailer.welcome.deliver
+ # ContactMailer.welcome.deliver_now
+ # ContactMailer.welcome.deliver_now
# end
# end
def assert_emails(number)
@@ -40,7 +40,7 @@ module ActionMailer
#
# def test_emails
# assert_no_emails
- # ContactMailer.welcome.deliver
+ # ContactMailer.welcome.deliver_now
# assert_emails 1
# end
#
diff --git a/guides/source/4_2_release_notes.md b/guides/source/4_2_release_notes.md
index aa056f5844..864026e9f2 100644
--- a/guides/source/4_2_release_notes.md
+++ b/guides/source/4_2_release_notes.md
@@ -311,6 +311,9 @@ Please refer to the [Changelog][action-mailer] for detailed changes.
* Deprecated `*_path` helpers in mailers. Always use `*_url` helpers instead.
([Pull Request](https://github.com/rails/rails/pull/15840))
+* Deprecated `deliver` / `deliver!` in favour of `deliver_now` / `deliver_now!`.
+ ([Pull Request](https://github.com/rails/rails/pull/16582))
+
### Notable changes
* Introduced `deliver_later` which enqueues a job on the application's queue
diff --git a/guides/source/action_mailer_basics.md b/guides/source/action_mailer_basics.md
index 9ad9319255..6b6ce145e4 100644
--- a/guides/source/action_mailer_basics.md
+++ b/guides/source/action_mailer_basics.md
@@ -159,7 +159,10 @@ $ bin/rake db:migrate
Now that we have a user model to play with, we will just edit the
`app/controllers/users_controller.rb` make it instruct the `UserMailer` to deliver
an email to the newly created user by editing the create action and inserting a
-call to `UserMailer.welcome_email` right after the user is successfully saved:
+call to `UserMailer.welcome_email` right after the user is successfully saved.
+
+Action Mailer is nicely integrated with Active Job so you can send emails outside
+of the request-response cycle, so the user doesn't have to wait on it:
```ruby
class UsersController < ApplicationController
@@ -171,7 +174,7 @@ class UsersController < ApplicationController
respond_to do |format|
if @user.save
# Tell the UserMailer to send a welcome email after save
- UserMailer.welcome_email(@user).deliver
+ UserMailer.welcome_email(@user).deliver_later
format.html { redirect_to(@user, notice: 'User was successfully created.') }
format.json { render json: @user, status: :created, location: @user }
@@ -184,8 +187,29 @@ class UsersController < ApplicationController
end
```
-The method `welcome_email` returns a `Mail::Message` object which can then just
-be told `deliver` to send itself out.
+NOTE: By default Active Job is configured to execute the job `:inline`. So you can
+use `deliver_later` now to send the emails and when you decide to start sending the
+email from a background job you'll just have to setup Active Job to use a queueing
+backend (Sidekiq, Resque, etc).
+
+If you want to send the emails right away (from a cronjob for example) just
+call `deliver_now`:
+
+```ruby
+class SendWeeklySummary
+ def run
+ User.find_each do |user|
+ UserMailer.weekly_summary(user).deliver_now
+ end
+ end
+end
+```
+
+The method `welcome_email` returns a `ActionMailer::MessageDelivery` object which
+can then just be told `deliver_now` or `deliver_later` to send itself out. The
+`ActionMailer::MessageDelivery` object is just a wrapper around a `Mail::Message`. If
+you want to inspect, alter or do anything else with the `Mail::Message` object you can
+access it with the `message` method on the `ActionMailer::MessageDelivery` object.
### Auto encoding header values
diff --git a/guides/source/active_job_basics.md b/guides/source/active_job_basics.md
index ae5d21d546..0df4320e36 100644
--- a/guides/source/active_job_basics.md
+++ b/guides/source/active_job_basics.md
@@ -196,10 +196,10 @@ of the request-response cycle, so the user doesn't have to wait on it. Active Jo
is integrated with Action Mailer so you can easily send emails async:
```ruby
-# Instead of the classic
-UserMailer.welcome(@user).deliver
+# If you want to send the email now use #deliver_now
+UserMailer.welcome(@user).deliver_now
-# use #deliver later to send the email async
+# If you want to send the email through ActiveJob use #deliver_later
UserMailer.welcome(@user).deliver_later
```
diff --git a/guides/source/active_record_querying.md b/guides/source/active_record_querying.md
index f9b46286c1..cb243c95f5 100644
--- a/guides/source/active_record_querying.md
+++ b/guides/source/active_record_querying.md
@@ -276,7 +276,7 @@ This may appear straightforward:
```ruby
# This is very inefficient when the users table has thousands of rows.
User.all.each do |user|
- NewsMailer.weekly(user).deliver
+ NewsMailer.weekly(user).deliver_now
end
```
@@ -292,7 +292,7 @@ The `find_each` method retrieves a batch of records and then yields _each_ recor
```ruby
User.find_each do |user|
- NewsMailer.weekly(user).deliver
+ NewsMailer.weekly(user).deliver_now
end
```
@@ -300,7 +300,7 @@ To add conditions to a `find_each` operation you can chain other Active Record m
```ruby
User.where(weekly_subscriber: true).find_each do |user|
- NewsMailer.weekly(user).deliver
+ NewsMailer.weekly(user).deliver_now
end
```
@@ -316,7 +316,7 @@ The `:batch_size` option allows you to specify the number of records to be retri
```ruby
User.find_each(batch_size: 5000) do |user|
- NewsMailer.weekly(user).deliver
+ NewsMailer.weekly(user).deliver_now
end
```
@@ -328,7 +328,7 @@ For example, to send newsletters only to users with the primary key starting fro
```ruby
User.find_each(start: 2000, batch_size: 5000) do |user|
- NewsMailer.weekly(user).deliver
+ NewsMailer.weekly(user).deliver_now
end
```
diff --git a/guides/source/testing.md b/guides/source/testing.md
index 2ecd560a87..d91f13699a 100644
--- a/guides/source/testing.md
+++ b/guides/source/testing.md
@@ -949,7 +949,7 @@ class UserMailerTest < ActionMailer::TestCase
test "invite" do
# Send the email, then test that it got queued
email = UserMailer.create_invite('me@example.com',
- 'friend@example.com', Time.now).deliver
+ 'friend@example.com', Time.now).deliver_now
assert_not ActionMailer::Base.deliveries.empty?
# Test the body of the sent email contains what we expect it to