Reputation: 8827
I implemented an authentication system using authlogic, and have added password reset functionality as per this tutorial http://github.com/rejeep/authlogic-password-reset-tutorial
It all works, but I am confused as to why it does..
There is this code..
class User < ActiveRecord::Base
def deliver_password_reset_instructions!
reset_perishable_token!
Notifier.deliver_password_reset_instructions(self)
end
end
and this
class Notifier < ActionMailer::Base
def password_reset_instructions(user)
subject "Password Reset Instructions"
from "[email protected]"
recipients user.email
content_type "text/html"
sent_on Time.now
body :edit_password_reset_url => edit_password_reset_url(user.perishable_token)
end
end
This line confuses me
Notifier.deliver_password_reset_instructions(self)
as the method in the Notifier class is called
password_reset_instructions
without the deliver_
bit.
So whats going on here? how come it all works?
Upvotes: 3
Views: 789
Reputation: 15492
Great Question, A lot of people forget to ask these questions.
Do you notice, that you never really Instantiate your mailer class objects. Your mailer class methods are usually wrapped with this deliver_<method_name>
So internally this uses the concept of method_missing
in ruby. Suppose you call a certain method in a ruby which doesn't exist for that object, ruby calls the method_missing
method. Which is defined in the "ActionMailer::Base" code
def method_missing(method_symbol, *parameters)#:nodoc: case method_symbol.id2name when /^create_([_a-z]\w*)/ then new($1, *parameters).mail when /^deliver_([_a-z]\w*)/ then new($1, *parameters).deliver! when "new" then nil else super end end
so if a method matches "deliver_" and any combination of lower cases letters, Rails instantiates your Mailer Class ( by calling the "new" ) and sends it with the parameters to the initializer and calls "deliver!" method to finally deliver the mail.
Same goes for "create_<method_name>" type methods
Upvotes: 3
Reputation: 176412
This is the Rails 2 ActionMailer convention.
To deliver an email, use YourMailerClass.deliver_NAME_OF_THE_METHOD
.
To initialize an email, use YourMailerClass.create_NAME_OF_THE_METHOD
.
Rails will automatically creates an instance of the Mailer class, call your method and deliver the email object.
Upvotes: 1