本文介绍了为什么 Rails 实例方法可以用作 rspec 中的类方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一篇关于在 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 中的类方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 23:11