in rails3 i defined a class
#coding:utf-8
clas开发者_开发百科s CoreMail < ActionMailer::Base
def consulting_reply(email)
mail(:to => email, :subject => 'ssss')
end
end
i found i could invoke this method like this
CoreMail.consulting_reply(email)
but want i thought the right way is :
instance=CoreMail.new
instance.consulting_reply(email)
because the consulting_reply is the instance method,
did i missing something? hope someone could give me a help
ActionMailer::Base
has a method_missing
defined on it:
def method_missing(method, *args) #:nodoc:
return super unless respond_to?(method)
new(method, *args).message
end
This will call your instance method with the same arguments and then call the message
method, returning the object of that mailer call. To deliver it, call deliver!
on the end of your method call:
CoreMail.consulting_reply(email).deliver!
You're right, normally that would be an instance method and you would have to create an instance of the class before calling consulting_reply() (since it's not defined as self.consulting_reply). However, your class is inheriting from ActionMailer::Base, and there's a little ruby magic happening behind the scenes. Checkout the source for ActionMailer::Base to see it for yourself (https://github.com/rails/rails/blob/master/actionmailer/lib/action_mailer/base.rb), but to simplify for you what's happening, here's a quick example:
class Test
def self.method_missing(method, *args)
puts "Called by a non class method"
end
end
Test.fake_class_method
Which will output:
Called by a non class method
ActionMailer::Base does something similar to this, which dynamically looks for the method you called. I believe it also creates a instance of the class using:
new(method, *args).message
Anyway, I hope this sheds some light as to what's happening.
精彩评论