最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

ruby - Rails ActionMailer default-method used in two classes: What's the difference? - Stack Overflow

programmeradmin2浏览0评论

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 0
Add a comment  | 

2 Answers 2

Reset to default 3

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: "[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

发布评论

评论列表(0)

  1. 暂无评论