Why Rails instance method can be used as class method in rspec

↘锁芯ラ 提交于 2019-12-20 03:22:54

问题


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

in this link: http://www.gotealeaf.com/blog/handling-emails-in-rails.

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?


回答1:


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

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.

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

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.



来源:https://stackoverflow.com/questions/30473664/why-rails-instance-method-can-be-used-as-class-method-in-rspec

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!