Here is a brief snippet from the guide on ActionMailer
    class UserMailer < ActionMailer::Base
  default :from => "[email protected]"
  def welcome_email(user)
    @user = user
    @url  = "http://example.com/login"
    mail(:to => user.email,
         :subject => "Welcome to My Awesome Site")
  end
end
And in the controller
class UsersController < ApplicationController
  # POST /users
  # POST /users.xml
  def create
    @user = User.new(params[:user])
    respond_to do |format|
      if @user.save
        # Tell the UserMailer to send a welcome Email after save
        UserMailer.welcome_email(@user).deliver
        format.html { redirect_to(@user, :notice => 'User was successfully created.') }
        format.xml  { render :xml => @user, :status => :created, :location => @user }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @user.errors, :status => :unprocessable_entity }
      end
    end
  end
end
So why is Rails trying to confuse rubyist with instance methods as class methods? I assume they've overridden missing method, but it just serves to confuse! Or am I missing something here?
ie why not define welcome_email as def self.welcome_email(user)
If it was #self.welcome_email you'd have to create an instance of the class yourself, which requires some configuration for all the default params etc.  Rails is just providing factory methods of the same name.
From a quick look at the source code, you're right, it does seem to use method_missing, where the mailer is actually created with:
mailer = TheMailer.new(:welcome_email, *args)
Rails does a lot of "voodoo" things like this, generally just to save the amount of code you write.  Just changing #welcome_email to be a class method would not give you an instance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With