From the ActionMailer-Documentation:
# app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
default from: "[email protected]"
# ...
end
... and ...
class UserMailer < ApplicationMailer
default from: "[email protected]"
# ...
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?
From the ActionMailer-Documentation:
# app/mailers/application_mailer.rb
class ApplicationMailer < ActionMailer::Base
default from: "[email protected]"
# ...
end
... and ...
class UserMailer < ApplicationMailer
default from: "[email protected]"
# ...
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?
Share Improve this question asked Mar 12 at 9:44 mewimewi 6232 gold badges5 silver badges14 bronze badges 02 Answers
Reset to default 3This 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: "[email protected]"
# ...
end
class FooMailer < ApplicationMailer
end
sandbox8(dev)> FooMailer.default[:from]
=> "[email protected]"
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: "[email protected]" }
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: "[email protected]"
# ...
end
You're changing the default values for instances of UserMailer. But other descendant classes of ApplicationMailer remain unchanged.
It's about Ruby inheritance
UserMailer
is child
ApplicationMailer
is parent
When invoke some mailer, Ruby tries to find methods in mailer_class.ancestors
array
If it is UserMailer
default from is [email protected]
because array looks like [UserMailer, ApplicationMailer, ...]
But if you define some new mailer without such defaults, let's say
class NewMailer < ApplicationMailer
end
this NewMailer
will use default of parent class — [email protected]
because NewMailer
hasn't own default from