When sending mail in Rails, usually one would do something like this:
在Rails中发送邮件时,通常可以这样做:
UserMailer.password_reset(user).deliver
But if we look inside UserMailer
we can see this:
但是,如果我们查看UserMailer,我们可以看到:
def password_reset(user) # not self.password_reset
# ...
end
Notice that the method name is not prefixed with self
. Looking at it, it seems like you need to instantiate the object first as below. How does Rails do this?
请注意,方法名称不以self为前缀。看一下,看起来你需要首先实例化对象,如下所示。 Rails如何做到这一点?
UserMailer.new.password_reset(user).deliver
2 个解决方案
#1
11
That's a great question. In the source (https://github.com/rails/rails/blob/master/actionmailer/lib/action_mailer/base.rb), Rails uses method_missing to create a new instance of the ActionMailer. Here's the relevant excerpt from the source:
这是一个很好的问题。在源代码(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
#2
0
Please note that the self.deliver
method is deprecated, have a look at the code given below. Since deliver
method is defined as a class method you don't have to instantiate the mailer class.
请注意,不推荐使用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
Sending mail
Once a mailer action and template are defined, you can deliver your message or create it and save it for delivery later:
定义邮件程序操作和模板后,您可以传递邮件或创建邮件并保存以供日后交付:
mail = Notifier.welcome(david) # => a Mail::Message object
mail.deliver # sends the email
#Above 2 steps can be combined
Notifier.welcome(david).deliver
You never instantiate your mailer class. Rather, you just call the method you defined on the class itself.
您永远不会实例化您的邮件程序类。相反,您只需调用您在类本身上定义的方法。
The method
password_reset
returns a Mail::Message object which can then just be told deliver to send itself out.password_reset方法返回一个Mail :: Message对象,然后可以告诉传递将其自身发送出去。
#1
11
That's a great question. In the source (https://github.com/rails/rails/blob/master/actionmailer/lib/action_mailer/base.rb), Rails uses method_missing to create a new instance of the ActionMailer. Here's the relevant excerpt from the source:
这是一个很好的问题。在源代码(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
#2
0
Please note that the self.deliver
method is deprecated, have a look at the code given below. Since deliver
method is defined as a class method you don't have to instantiate the mailer class.
请注意,不推荐使用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
Sending mail
Once a mailer action and template are defined, you can deliver your message or create it and save it for delivery later:
定义邮件程序操作和模板后,您可以传递邮件或创建邮件并保存以供日后交付:
mail = Notifier.welcome(david) # => a Mail::Message object
mail.deliver # sends the email
#Above 2 steps can be combined
Notifier.welcome(david).deliver
You never instantiate your mailer class. Rather, you just call the method you defined on the class itself.
您永远不会实例化您的邮件程序类。相反,您只需调用您在类本身上定义的方法。
The method
password_reset
returns a Mail::Message object which can then just be told deliver to send itself out.password_reset方法返回一个Mail :: Message对象,然后可以告诉传递将其自身发送出去。