From the ActionMailer-Documentation:
# app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
default from: "from@example.com"
# ...
end
... and ...
class UserMailer < ApplicationMailer
default from: "notifications@example.com"
# ...
end
The default-method is used two times. The usage in the UserMailer is explained: "The default method sets default values for all emails sent from this mailer."
But what does the default-method in the ApplicationMailer?
Which effect is accomplished by the TWO invocations in different classes in the end?
This is just inheritance but with a little twist from ActiveSupport. The default value of the parent class becomes the default for any subclass.
class ApplicationMailer < ActionMailer::Base
default from: "from@example.com"
# ...
end
class FooMailer < ApplicationMailer
end
sandbox8(dev)> FooMailer.default[:from]
=> "from@example.com"
The default parameters are stored as a class attribute:
class_attribute :default_params, default: {
mime_version: "1.0",
charset: "UTF-8",
content_type: "text/plain",
parts_order: [ "text/plain", "text/enriched", "text/html" ]
}.freeze
Class attributes are an ActiveSupport construct that are used somewhat like class variables but avoid the major pitfall of class variables which is that they are shared between a class and it's subclasses. This is something that ActiveSupport builds with the basic building blocks provided by Ruby and isn't inherent to the language.
What the default
method does replace this class attribute with a merger between the existing defaults and the passed hash:
# Allows to set defaults through app configuration:
#
# config.action_mailer.default_options = { from: "no-reply@example.org" }
def default(value = nil)
self.default_params = default_params.merge(value).freeze if value
default_params
end
This ensures that you're not modifying the existing object - which would effect subclasses.
So when you do:
class UserMailer < ApplicationMailer
default from: "notifications@example.com"
# ...
end
You're changing the default values for instances of UserMailer. But other descendant classes of ApplicationMailer remain unchanged.