From 7a64c9482b7efd43f770d062eb7f65efe637c1e1 Mon Sep 17 00:00:00 2001 From: Jonathan Hefner Date: Fri, 20 Nov 2020 16:49:46 -0600 Subject: [PATCH] Link to API docs in Action Mailer Basics guide [ci-skip] This links the first mention of each method to its API documentation, similar to a Wikipedia article. Some subsequent mentions are also linked, when it suits the surrounding text. This also modifies the text in a few places to ensure that methods are explicitly mentioned and linked. --- guides/source/action_mailer_basics.md | 97 +++++++++++++++++++-------- 1 file changed, 68 insertions(+), 29 deletions(-) diff --git a/guides/source/action_mailer_basics.md b/guides/source/action_mailer_basics.md index 8fb302ad80..e46ba3d920 100644 --- a/guides/source/action_mailer_basics.md +++ b/guides/source/action_mailer_basics.md @@ -24,7 +24,7 @@ and views. #### Mailers are similar to controllers -They inherit from `ActionMailer::Base` and live in `app/mailers`. Mailers also work +They inherit from [`ActionMailer::Base`][] and live in `app/mailers`. Mailers also work very similarly to controllers. Some examples of similarities are enumerated below. Mailers have: @@ -33,6 +33,8 @@ Mailers have: * The ability to utilise layouts and partials. * The ability to access a params hash. +[`ActionMailer::Base`]: https://api.rubyonrails.org/classes/ActionMailer/Base.html + Sending Emails -------------- @@ -111,11 +113,14 @@ Here is a quick explanation of the items presented in the preceding method. For a full list of all available options, please have a look further down at the Complete List of Action Mailer user-settable attributes section. -* `default Hash` - This is a hash of default values for any email you send from -this mailer. In this case we are setting the `:from` header to a value for all +* The [`default`][] method sets default values for all emails sent from +this mailer. In this case, we use it to set the `:from` header value for all messages in this class. This can be overridden on a per-email basis. -* `mail` - The actual email message, we are passing the `:to` and `:subject` -headers in. +* The [`mail`][] method creates the actual email message. We use it to specify +the values of headers like `:to` and `:subject` per email. + +[`default`]: https://api.rubyonrails.org/classes/ActionMailer/Base.html#method-c-default +[`mail`]: https://api.rubyonrails.org/classes/ActionMailer/Base.html#method-i-mail #### Create a Mailer View @@ -182,8 +187,9 @@ Now that we have a user model to play with, we will edit the an email to the newly created user by editing the create action and inserting a call to `UserMailer.with(user: @user).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: +We will enqueue the email to be sent by using [`deliver_later`][], which is +backed by Active Job. That way, the controller action can continue without +waiting for the send to complete. ```ruby class UsersController < ApplicationController @@ -208,7 +214,7 @@ class UsersController < ApplicationController end ``` -NOTE: Active Job's default behavior is to execute jobs via the `:async` adapter. +NOTE: Active Job's default behavior is to execute jobs via the `:async` adapter. So, you can use `deliver_later` to send emails asynchronously. Active Job's default adapter runs jobs with an in-process thread pool. It's well-suited for the development/test environments, since it doesn't require @@ -220,7 +226,7 @@ that has a persistent backend (Sidekiq, Resque, etc). NOTE: When calling `deliver_later` the job will be placed under `mailers` queue. Make sure Active Job adapter supports this queue, otherwise the job may be silently ignored preventing email delivery. You can change this queue name by specifying `config.action_mailer.deliver_later_queue_name` option. If you want to send emails right away (from a cronjob for example) just call -`deliver_now`: +[`deliver_now`][]: ```ruby class SendWeeklySummary @@ -232,16 +238,23 @@ class SendWeeklySummary end ``` -Any key value pair passed to `with` just becomes the `params` for the mailer +Any key value pair passed to [`with`][] just becomes the `params` for the mailer action. So `with(user: @user, account: @user.account)` makes `params[:user]` and `params[:account]` available in the mailer action. Just like controllers have params. -The method `welcome_email` returns an `ActionMailer::MessageDelivery` object which +The method `welcome_email` returns an [`ActionMailer::MessageDelivery`][] object which can then be told to `deliver_now` or `deliver_later` to send itself out. The -`ActionMailer::MessageDelivery` object is a wrapper around a `Mail::Message`. If +`ActionMailer::MessageDelivery` object is 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. +access it with the [`message`][] method on the `ActionMailer::MessageDelivery` object. + +[`ActionMailer::MessageDelivery`]: https://api.rubyonrails.org/classes/ActionMailer/MessageDelivery.html +[`deliver_later`]: https://api.rubyonrails.org/classes/ActionMailer/MessageDelivery.html#method-i-deliver_later +[`deliver_now`]: https://api.rubyonrails.org/classes/ActionMailer/MessageDelivery.html#method-i-deliver_now +[`Mail::Message`]: https://api.rubyonrails.org/classes/Mail/Message.html +[`message`]: https://api.rubyonrails.org/classes/ActionMailer/MessageDelivery.html#method-i-message +[`with`]: https://api.rubyonrails.org/classes/ActionMailer/Parameterized/ClassMethods.html#method-i-with ### Auto encoding header values @@ -257,15 +270,18 @@ self-encoding text first, please refer to the There are just three methods that you need to send pretty much any email message: -* `headers` - Specifies any header on the email you want. You can pass a hash of +* [`headers`][] - Specifies any header on the email you want. You can pass a hash of header field names and value pairs, or you can call `headers[:field_name] = 'value'`. -* `attachments` - Allows you to add attachments to your email. For example, +* [`attachments`][] - Allows you to add attachments to your email. For example, `attachments['file-name.jpg'] = File.read('file-name.jpg')`. -* `mail` - Sends the actual email itself. You can pass in headers as a hash to +* [`mail`][] - Creates the actual email itself. You can pass in headers as a hash to the mail method as a parameter, mail will then create an email, either plain text, or multipart, depending on what email templates you have defined. +[`attachments`]: https://api.rubyonrails.org/classes/ActionMailer/Base.html#method-i-attachments +[`headers`]: https://api.rubyonrails.org/classes/ActionMailer/Base.html#method-i-headers + #### Adding Attachments Action Mailer makes it very easy to add attachments. @@ -358,7 +374,7 @@ The same format can be used to set carbon copy (Cc:) and blind carbon copy #### Sending Email With Name Sometimes you wish to show the name of the person instead of just their email -address when they receive the email. You can use `email_address_with_name` for +address when they receive the email. You can use [`email_address_with_name`][] for that: ```ruby @@ -371,6 +387,8 @@ def welcome_email end ``` +[`email_address_with_name`]: https://api.rubyonrails.org/classes/ActionMailer/Base.html#method-i-email_address_with_name + ### Mailer Views Mailer views are located in the `app/views/name_of_mailer_class` directory. The @@ -424,7 +442,7 @@ use the rendered text for the text part. The render command is the same one used inside of Action Controller, so you can use all the same options, such as `:text`, `:inline` etc. -If you would like to render a template located outside of the default `app/views/mailer_name/` directory, you can apply the `prepend_view_path`, like so: +If you would like to render a template located outside of the default `app/views/mailer_name/` directory, you can apply the [`prepend_view_path`][], like so: ```ruby class UserMailer < ApplicationMailer @@ -437,11 +455,14 @@ class UserMailer < ApplicationMailer end ``` -You can also consider using the [append_view_path](https://guides.rubyonrails.org/action_view_overview.html#view-paths) method. +You can also consider using the [`append_view_path`][] method. + +[`append_view_path`]: https://api.rubyonrails.org/classes/ActionView/ViewPaths/ClassMethods.html#method-i-append_view_path +[`prepend_view_path`]: https://api.rubyonrails.org/classes/ActionView/ViewPaths/ClassMethods.html#method-i-prepend_view_path #### Caching mailer view -You can perform fragment caching in mailer views like in application views using the `cache` method. +You can perform fragment caching in mailer views like in application views using the [`cache`][] method. ```html+erb <% cache do %> @@ -458,6 +479,8 @@ config.action_mailer.perform_caching = true Fragment caching is also supported in multipart emails. Read more about caching in the [Rails caching guide](caching_with_rails.html). +[`cache`]: https://api.rubyonrails.org/classes/ActionView/Helpers/CacheHelper.html#method-i-cache + ### Action Mailer Layouts Just like controller views, you can also have mailer layouts. The layout name @@ -465,7 +488,7 @@ needs to be the same as your mailer, such as `user_mailer.html.erb` and `user_mailer.text.erb` to be automatically recognized by your mailer as a layout. -In order to use a different file, call `layout` in your mailer: +In order to use a different file, call [`layout`][] in your mailer: ```ruby class UserMailer < ApplicationMailer @@ -493,6 +516,8 @@ end Will render the HTML part using the `my_layout.html.erb` file and the text part with the usual `user_mailer.text.erb` file if it exists. +[`layout`]: https://api.rubyonrails.org/classes/ActionView/Layouts/ClassMethods.html#method-i-layout + ### Previewing Emails Action Mailer previews provide a way to see how emails look by visiting a @@ -556,7 +581,7 @@ By using the full URL, your links will now work in your emails. #### Generating URLs with `url_for` -`url_for` generates a full URL by default in templates. +[`url_for`][] generates a full URL by default in templates. If you did not configure the `:host` option globally make sure to pass it to `url_for`. @@ -568,6 +593,8 @@ If you did not configure the `:host` option globally make sure to pass it to action: 'greeting') %> ``` +[`url_for`]: https://api.rubyonrails.org/classes/ActionView/RoutingUrlFor.html#method-i-url_for + #### Generating URLs with Named Routes Email clients have no web context and so paths have no base URL to form complete @@ -656,8 +683,8 @@ end Action Mailer Callbacks ----------------------- -Action Mailer allows for you to specify a `before_action`, `after_action` and -`around_action`. +Action Mailer allows for you to specify a [`before_action`][], [`after_action`][] and +[`around_action`][]. * Filters can be specified with a block or a symbol to a method in the mailer class similar to controllers. @@ -730,6 +757,10 @@ end * Mailer Filters abort further processing if body is set to a non-nil value. +[`after_action`]: https://api.rubyonrails.org/classes/AbstractController/Callbacks/ClassMethods.html#method-i-after_action +[`around_action`]: https://api.rubyonrails.org/classes/AbstractController/Callbacks/ClassMethods.html#method-i-around_action +[`before_action`]: https://api.rubyonrails.org/classes/AbstractController/Callbacks/ClassMethods.html#method-i-before_action + Using Action Mailer Helpers --------------------------- @@ -737,14 +768,18 @@ Action Mailer inherits from `AbstractController`, so you have access to most of the same helpers as you do in Action Controller. There are also some Action Mailer-specific helper methods available in -`ActionMailer::MailHelper`. For example, these allow accessing the mailer -instance from your view with `mailer`, and accessing the message as `message`: +[`ActionMailer::MailHelper`][]. For example, these allow accessing the mailer +instance from your view with [`mailer`][MailHelper#mailer], and accessing the message as [`message`][MailHelper#message]: ```erb <%= stylesheet_link_tag mailer.name.underscore %>

<%= message.subject %>

``` +[`ActionMailer::MailHelper`]: https://api.rubyonrails.org/classes/ActionMailer/MailHelper.html +[MailHelper#mailer]: https://api.rubyonrails.org/classes/ActionMailer/MailHelper.html#method-i-mailer +[MailHelper#message]: https://api.rubyonrails.org/classes/ActionMailer/MailHelper.html#method-i-message + Action Mailer Configuration --------------------------- @@ -827,8 +862,8 @@ class SandboxEmailInterceptor end ``` -Before the interceptor can do its job you need to register it with the Action -Mailer framework. You can do this in an initializer file +Before the interceptor can do its job you need to register it using +[`register_interceptor`][]. You can do this in an initializer file `config/initializers/sandbox_email_interceptor.rb` ```ruby @@ -842,6 +877,8 @@ production like server but for testing purposes. You can read [Creating Rails environments](configuring.html#creating-rails-environments) for more information about custom Rails environments. +[`register_interceptor`]: https://api.rubyonrails.org/classes/ActionMailer/Base.html#method-c-register_interceptor + ### Observing Emails Observers give you access to the email message after it has been sent. An observer class must implement the `:delivered_email(message)` method, which will be called after the email is sent. @@ -853,9 +890,11 @@ class EmailDeliveryObserver end end ``` -Like interceptors, you need to register observers with the Action Mailer framework. You can do this in an initializer file +Similar to interceptors, you must register observers using [`register_observer`][]. You can do this in an initializer file `config/initializers/email_delivery_observer.rb` ```ruby ActionMailer::Base.register_observer(EmailDeliveryObserver) ``` + +[`register_observer`]: https://api.rubyonrails.org/classes/ActionMailer/Base.html#method-c-register_observer