为什么Rails实例方法可以用作rspec中的类方法

我在一篇关于在Rails应用程序中发送邮件的文章中找到了一个片段:

class ExampleMailerPreview < ActionMailer::Preview def sample_mail_preview ExampleMailer.sample_email(User.first) end end 

在此链接: http : //www.gotealeaf.com/blog/handling-emails-in-rails 。

我不知道为什么方法: sample_email() ,在我看来应该是一个实例方法,可以像ExampleMailer.sample_email()一样在类方法中访问。 谁有人解释一下?

它不是一个rspec的东西,它是一个ActionMailer的东西。 看着:

https://github.com/rails/rails/blob/master/actionmailer/lib/action_mailer/base.rb

看一下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 ActionMailer::MessageDelivery class is a wrapper around a delegate that will call # your method to generate the mail. If you want direct access to delegator, or Mail::Message, # you can call the message method on the ActionMailer::MessageDelivery object. 

通过在ActionMailer :: Base类上定义一个method_missing方法来实现该function,该方法如下所示:

  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类的新实例。