Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActionMailer instance method being used like class method

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)

like image 505
Syed Ali Avatar asked Jun 16 '11 06:06

Syed Ali


1 Answers

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.

like image 129
d11wtq Avatar answered Nov 16 '22 03:11

d11wtq