问题描述
我在一篇关于在 Rails 应用程序中发送邮件的文章中找到了一个片段:
I found a snippet in an article about sending mails in a Rails application:
class ExampleMailerPreview < ActionMailer::Preview
def sample_mail_preview
ExampleMailer.sample_email(User.first)
end
end
在此链接中:http://www.gotealeaf.com/blog/处理电子邮件轨道.
我不知道为什么这个方法:sample_email()
,在我看来应该是一个实例方法,可以像这里的类方法一样访问 ExampleMailer.sample_email()
代码>.谁能解释一下?
I do not know why the method: sample_email()
, which in my mind should be an instance method, can be accessed like class method here as ExampleMailer.sample_email()
. Can anyone explain?
推荐答案
这不是 rspec 的事情,而是 ActionMailer 的事情.看着:
It's not an rspec thing, it's an ActionMailer thing. Looking at:
https://github.com/rails/rails/blob/master/actionmailer/lib/action_mailer/base.rb
看看第 135-146 行的注释:
Take a look at the comments in lines 135-146:
# = Sending mail
#
# Once a mailer action and template are defined, you can deliver your message or defer its creation and
# delivery for later:
#
# NotifierMailer.welcome(User.first).deliver_now # sends the email
# mail = NotifierMailer.welcome(User.first) # => an ActionMailer::MessageDelivery object
# mail.deliver_now # generates and sends the email now
#
# The <tt>ActionMailer::MessageDelivery</tt> class is a wrapper around a delegate that will call
# your method to generate the mail. If you want direct access to delegator, or <tt>Mail::Message</tt>,
# you can call the <tt>message</tt> method on the <tt>ActionMailer::MessageDelivery</tt> object.
该功能是通过在 ActionMailer::Base 类上定义一个 method_missing 方法来实现的,如下所示:
The functionality is implemented by defining a method_missing method on the ActionMailer::Base class that looks like:
def method_missing(method_name, *args) # :nodoc:
if action_methods.include?(method_name.to_s)
MessageDelivery.new(self, method_name, *args)
else
super
end
end
本质上,在 ActionMailer 实例(注释示例中的 NotifierMailer)上定义一个方法,然后在类上调用它会创建一个新的 MessageDelivery 实例,该实例委托给 ActionMailer 类的一个新实例.
Essentially, defining a method on an ActionMailer instance (NotifierMailer in the comment example) and then calling it on the class creates a new MessageDelivery instance which delegates to a new instance of the ActionMailer class.
这篇关于为什么 Rails 实例方法可以用作 rspec 中的类方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!