如果没有这样定义,你怎么能在邮件程序上调用类方法呢?
在Rails中发送邮件时,通常可以这样做:
UserMailer.password_reset(user).deliver
但是,如果我们查看UserMailer
我们可以看到:
def password_reset(user) # not self.password_reset # ... end
请注意,方法名称不以self
为前缀。 看一下,看起来你需要首先实例化对象,如下所示。 Rails如何做到这一点?
UserMailer.new.password_reset(user).deliver
这是一个很好的问题。 在源代码( https://github.com/rails/rails/blob/master/actionmailer/lib/action_mailer/base.rb )中,Rails使用method_missing创建ActionMailer的新实例。 以下是来源的相关摘录:
def method_missing(method_name, *args) # :nodoc: if respond_to?(method_name) new(method_name, *args).message else super end end
请注意,不推荐使用self.deliver
方法,请查看下面给出的代码。 由于deliver
方法被定义为类方法,因此您不必实例化邮件程序类。
action_mailer / deprecated_api.rb
module ActionMailer module DeprecatedApi #:nodoc: extend ActiveSupport::Concern module ClassMethods # Deliver the given mail object directly. This can be used to deliver # a preconstructed mail object, like: # # email = MyMailer.create_some_mail(parameters) # email.set_some_obscure_header "frobnicate" # MyMailer.deliver(email) def deliver(mail, show_warning=true) if show_warning ActiveSupport::Deprecation.warn "#{self}.deliver is deprecated, call " << "deliver in the mailer instance instead", caller[0,2] end raise "no mail object available for delivery!" unless mail wrap_delivery_behavior(mail) mail.deliver mail end
发送邮件
定义邮件程序操作和模板后,您可以传递邮件或创建邮件并保存以供日后交付:
mail = Notifier.welcome(david) # => a Mail::Message object mail.deliver # sends the email #Above 2 steps can be combined Notifier.welcome(david).deliver
您永远不会实例化您的邮件程序类。 相反,您只需调用您在类本身上定义的方法。
password_reset
方法返回一个Mail :: Message对象,然后可以告诉传递将其自身发送出去。