Q:

Understanding Rails ActionMailer coding

I am bit confused about  ActionMailer coding. 
A standard action mailer example
app/mailers/example_mailer.rb
class ExampleMailer < ActionMailer::Base
  default from: "from@example.com"

  def sample_email(user)
    @user = user
    mail(to: @user.email, subject: 'Sample Email')
  end
end

app/controllers/users_controller.rb
def create
  @user = User.new(user_params)

  respond_to do |format|
    if @user.save

      # Sends email to user when user is created.
      ExampleMailer.sample_email(@user).deliver_now

      format.html { redirect_to @user, notice: 'User was successfully created.' }
      format.json { render :show, status: :created, location: @user }
    else
      format.html { render :new }
      format.json { render json: @user.errors, status: :unprocessable_entity }
    end
  end
end

My questions are related to 
ExampleMailer.sample_email(@user).deliver_now

How ExampleMailer access sample_email method without ExampleMailer.new? sample_email is not a class  method!
How deliver_now call ExampleMailer ?

I hope it is clear. Any help appreciated.

A:

You're right that sample_email is not a class method, it's an instance method. But ExampleMailer inherits from ActionMailer::Base that does some clever meta-programming.
When you call ExampleMailer.simple_email it doesn't find a class method, so that automatically calls the private method method_missing.  
In method_missing it checks if the instance method exists, creates a mailer instance object (so it basically does the .new for you), calls the instance method on the mailer object, and then returns the object... and on that object, you called the deliver_now or deliver_later method since you specified those methods in your original line.  Basically the same as if you did...
my_mail_thing = ExampleMailer.sample_email(@user)
my_mail_thing.deliver_now

However, if ExampleMailer doesn't find the instance method, it falls back on the standard missing responses e.g. "NoMetihodError:: undefined method 'another_simple_email' for ExampleMail.:Class"
It's all pretty amazing.  You can read more about method_missing by googling the term, and you can experiment on your own classes.

