When you call deliver (or prepare) on a mailer, the keyword arguments you pass are the mailer’s input. Exposures turn that input into the values your headers, templates, attachments and delivery options need.
welcome_mailer.deliver(user: {name: "Alice", email: "alice@example.com"})
Here user: is the input. An exposure makes it available for rendering:
from "welcome@bookshelf.test"
to { user[:email] }
subject { "Welcome, !" }
expose :user
end
Defining exposures
expose comes in a few forms.
A value passed straight through from the input:
expose :user
A value computed by a block:
expose(:greeting) { "Hello, !" }
A default for optional input, used when the input has no matching key:
expose :greeting, default: "Hello"
Expose several pass-through values at once:
expose :user, :order
An exposure’s value comes from the first of these that applies: the given block, an instance method matching the name, or the matching key in the input (falling back to :default).
The block parameter rule
Exposures, the header methods, attachment blocks and delivery option blocks all follow one rule for their block parameters:
- Keyword parameters receive matching keys from the input. Give them defaults to make those keys optional.
- Positional parameters receive exposure values, matched by name.
This lets later declarations build on earlier exposures:
from "orders@bookshelf.test"
# `customer:` comes from the input given to `deliver`
to { customer[:email] }
# `customer:` comes from the input; `greeting` becomes an exposure
expose :greeting do
"Hello, !"
end
# `greeting` (positional) receives the value from the `:greeting` exposure above
subject { greeting }
end
OrderMailer.new.deliver(customer: {name: "Alice", email: "alice@example.com"})
A keyword splat (**input) receives the entire input:
expose :summary do
input.keys.join(", ")
end
Private exposures
A private exposure is computed and stays available as a dependency to your other exposures, headers, attachments and delivery options, but is never passed to the view for rendering. Use it for values you need while building the message, but don’t want in your templates:
from "billing@bookshelf.test"
to { email }
subject { "Invoice for " }
private_expose :full_name do
" "
end
end
private_expose is shorthand for expose(..., private: true).
Next steps
- Headers puts the parameter rule to work across all the standard and custom email headers.
- Templates and rendering covers how exposures reach your templates, including decorating them with view parts.