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

后端 未结 1 909
终归单人心
终归单人心 2021-01-21 19:05

I found a snippet in an article about sending mails in a Rails application:

class ExampleMailerPreview < ActionMailer::Preview
  def sample_mail_preview
    E         


        
1条回答
  •  有刺的猬
    2021-01-21 19:39

    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 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.
    

    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.

    0 讨论(0)
提交回复
热议问题