<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Flvorful Bloggage: Tag DIR</title>
    <link>http://blog.flvorful.com/articles/tag/dir</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description></description>
    <item>
      <title>Deep in Rails: ActionMailer#deliver Part VI</title>
      <description>&lt;p&gt;So now we know how Rails sends emails.  What can we do with that knowledge?&lt;/p&gt;

&lt;p&gt;All kinds of stuff.&lt;/p&gt;

&lt;p&gt;One of my clients needed the ability to send messages through 3 different &lt;span class="caps"&gt;SMTP&lt;/span&gt; servers.  They wanted it to be easy to use for their developers and allow them to change out &lt;span class="caps"&gt;SMTP&lt;/span&gt; servers for each mailer method.  Now that we know how AM does it&#8217;s thing, we can use that knowledge to create a quick patch and solve the above problem.&lt;/p&gt;

&lt;p&gt;We&#8217;ll create a new file in out Rails app inside lib/ and call it &lt;code&gt;action_mailer_hacks.rb&lt;/code&gt;.  Inside of the file add the following (dont worry, we&#8217;ll go over each line)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module ActionMailerHacks

    module InstanceMethods
        def deliver_with_switchable_smtp!(mail = @mail)
            unless logger.nil?
                logger.info  "Switching SMTP server to: #{new_smtp.inspect}" 
            end
            ActionMailer::Base.smtp_settings = new_smtp unless new_smtp.nil?
            deliver_without_switchable_smtp!(mail = @mail)
        end

    end

    def self.included(receiver)
        receiver.send :include, InstanceMethods
        receiver.class_eval do
            adv_attr_accessor :new_smtp
            alias_method_chain :deliver!, :switchable_smtp
        end
    end
end

ActionMailer::Base.send :include, ActionMailerHacks
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;First, in &lt;code&gt;module InstanceMethods&lt;/code&gt;, we create a new deliver method that will switch the &lt;span class="caps"&gt;SMTP&lt;/span&gt; server from AM.  We do some quick logging and then set &lt;code&gt;AM::Base.smtp_settings&lt;/code&gt; to the new smtp server.  After we do that, we call &lt;code&gt;deliver_without_switchable_smtp&lt;/code&gt; which gets created when we do our &lt;em&gt;alias_method_chaining&lt;/em&gt; later down the page.&lt;/p&gt;

&lt;p&gt;When this module is included we include the &lt;code&gt;InstanceMethods&lt;/code&gt; module into the receiver and then run &lt;code&gt;class_eval&lt;/code&gt; so that we can create a new &lt;code&gt;adv_attr_accessor&lt;/code&gt; called &lt;code&gt;new_smtp&lt;/code&gt; and then call &lt;code&gt;alias_method_chain&lt;/code&gt; to create our &lt;code&gt;without&lt;/code&gt; method.  After that we include this whole module into AM::Base and we&#8217;re done with the hack.  Add &lt;code&gt;require "action_mailer_hacks.rb"&lt;/code&gt; to your &lt;code&gt;environment.rb&lt;/code&gt; file and we&#8217;re ready for the mailer.&lt;/p&gt;

&lt;p&gt;Now we move on to MessageMailer and actually use the hack.&lt;/p&gt;

&lt;pre id="scroll_to_here" &gt;&lt;code&gt;class MessageMailer &amp;lt; ActionMailer::Base
  def contact_form(msg_from, message)
    subject    'Im contacting you'
    recipients "someemail@somedomain.com" 
        new_smtp   :address =&amp;gt; 'mail.someplace.com', :port =&amp;gt; 25, :domain =&amp;gt; 'someplace.com', :authentication =&amp;gt; :login, :user_name =&amp;gt; 'xxxxdddd', :password =&amp;gt; 'secret'
    from       msg_from
    sent_on    Time.now
    body       :message =&amp;gt; message
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;All we do is call &lt;code&gt;new_smtp&lt;/code&gt; with our new server address and then this method gets delivered through that &lt;span class="caps"&gt;SMTP&lt;/span&gt; server.  That&#8217;s it.  Simple and clean, exactly how I like it.&lt;/p&gt;

&lt;p&gt;Well, that was fun.  Next time, we&#8217;ll look through something a little shorter, maybe migrations.  Until then, have fun and keep codin&#8217;&lt;/p&gt;</description>
      <pubDate>Sun, 20 Dec 2009 09:41:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:f0e64747-3896-444c-b2ae-d02320362aa1</guid>
      <author>jake</author>
      <link>http://blog.flvorful.com/articles/2009/12/20/deep-in-rails-actionmailer-deliver-part-vi</link>
      <category>Rails</category>
      <category>rails</category>
      <category>action_mailer</category>
      <category>deep</category>
      <category>DIR</category>
      <category>part4</category>
    </item>
    <item>
      <title>Deep in Rails: ActionMailer#deliver Part V</title>
      <description>&lt;p&gt;So now we have our mail object.  Let&amp;#8217;s send it. &lt;/p&gt;

&lt;p&gt;For the sending of the message, we need to go back to the beginning, &lt;code&gt;method_missing&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(line 62 action_mailer/base.rb)
def method_missing(method_symbol, *parameters) #:nodoc:
  if match = matches_dynamic_method?(method_symbol)

    case match[1]
      when 'create'  then new(match[2], *parameters).mail
      when 'deliver' then new(match[2], *parameters).deliver!
      when 'new'     then nil
      else super
    end
  else
    super
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You remember &lt;code&gt;method_missing&lt;/code&gt; from a long time ago.  We just finished the first part of the line:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;when 'deliver' then new(match[2], *parameters).deliver!
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We created the new AM object and now we call &lt;code&gt;deliver!&lt;/code&gt; on it.  That&amp;#8217;s our next stop:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(line 520 action_mailer/base.rb)
def deliver!(mail = @mail)
  raise "no mail object available for delivery!" unless mail
  unless logger.nil?
    logger.info  "Sent mail to #{Array(recipients).join(', ')}"
    logger.debug "\n#{mail.encoded}"
  end

  begin
    __send__("perform_delivery_#{delivery_method}", mail) if perform_deliveries
  rescue Exception =&amp;gt; e  # Net::SMTP errors or sendmail pipe errors
    raise e if raise_delivery_errors
  end

  return mail
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The beginning of this method does some checking and logging.  The main part of this method is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;__send__("perform_delivery_#{delivery_method}", mail) if perform_deliveries
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We are again using &lt;code&gt;__send__&lt;/code&gt; to bypass any possible overridden method and calling &lt;code&gt;perform_delivery_#{delivery_method}&lt;/code&gt; with the mail object.  &lt;code&gt;delivery_method&lt;/code&gt; is a configuration attribute on the AM class along with &lt;code&gt;perform_deliveries&lt;/code&gt;.  AM defaults to &amp;#8220;smtp&amp;#8221; for &lt;code&gt;delivery_method&lt;/code&gt; and &amp;#8220;true&amp;#8221; for &lt;code&gt;perform_deliveries&lt;/code&gt; so the method we end up calling in our example is &lt;code&gt;perform_delivery_smtp&lt;/code&gt;.  Let&amp;#8217;s see that code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(line 680 action_mailer/base.rb)
def perform_delivery_smtp(mail)
  destinations = mail.destinations
  mail.ready_to_send
  sender = (mail['return-path'] &amp;amp;&amp;amp; mail['return-path'].spec) || mail.from

  smtp = Net::SMTP.new(smtp_settings[:address], smtp_settings[:port])
  smtp.enable_starttls_auto if smtp_settings[:enable_starttls_auto] &amp;amp;&amp;amp; smtp.respond_to?(:enable_starttls_auto)
  smtp.start(smtp_settings[:domain], smtp_settings[:user_name], smtp_settings[:password],
             smtp_settings[:authentication]) do |smtp|
    smtp.sendmail(mail.encoded, sender, destinations)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is the finale.  The climax.  The whole reason we even engage in &lt;code&gt;ActionMailer&lt;/code&gt;, to actualy send an email.  Here we go.&lt;/p&gt;

&lt;p&gt;The first line pulls the &lt;code&gt;destinations&lt;/code&gt; (recipients) from the mail object and stores them in a variable.  Next, we call &lt;code&gt;ready_to_send&lt;/code&gt; on the mail object which is also the TMail object (remember that we assigned the final TMail object to the @mail attribute on our AM object).  This method is defined in &lt;code&gt;TMail::Net&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(line 62 action_mailer/tmail-1.2.3/tmail-1.2.3/net.rb)
def ready_to_send
  delete_no_send_fields
  add_message_id
  add_date
end

NOSEND_FIELDS = %w(
  received
  bcc
)

def delete_no_send_fields
  NOSEND_FIELDS.each do |nm|
    delete nm
  end
  delete_if {|n,v| v.empty? }
end

def add_message_id( fqdn = nil )
  self.message_id = ::TMail::new_message_id(fqdn)
end

def add_date
  self.date = Time.now
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, if you scan through that code you may notice that we are calling &lt;code&gt;delete&lt;/code&gt; and &lt;code&gt;delete_if&lt;/code&gt; like we were in a standard &lt;code&gt;Enumerable&lt;/code&gt; object, but we are not.  TMail also defines those methods:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def delete( key )
  @header.delete key.downcase
end

def delete_if
  @header.delete_if do |key,val|
    if Array === val
      val.delete_if {|v| yield key, v }
      val.empty?
    else
      yield key, val
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What we are doing with all this is stripping and setting some defaults.  &lt;code&gt;delete_no_send_fields&lt;/code&gt; get&amp;#8217;s rid of the &amp;#8220;received&amp;#8221; and &amp;#8220;bcc&amp;#8221; keys from our header and we are getting rid of any headers that have empty values.  After that we set a nice new hex type id for this email with &lt;code&gt;TMail.new_message_id&lt;/code&gt; which is defined in &lt;code&gt;TMail::Utils&lt;/code&gt; which gives us a string with a hex code attached to your machine&amp;#8217;s hostname.  The last line adds the date to the mail message and that&amp;#8217;s it.&lt;/p&gt;

&lt;p&gt;The next line sets the sender attribute.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sender = (mail['return-path'] &amp;amp;&amp;amp; mail['return-path'].spec) || mail.from
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we get into the actual sending of the email.  We aren&amp;#8217;t going to go into it because it is part of Ruby&amp;#8217;s core lib, but we will quickly skim over it to see what&amp;#8217;s going on:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;smtp = Net::SMTP.new(smtp_settings[:address], smtp_settings[:port])
smtp.enable_starttls_auto if smtp_settings[:enable_starttls_auto] &amp;amp;&amp;amp; smtp.respond_to?(:enable_starttls_auto)
smtp.start(smtp_settings[:domain], smtp_settings[:user_name], smtp_settings[:password],
           smtp_settings[:authentication]) do |smtp|
  smtp.sendmail(mail.encoded, sender, destinations)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;First, we create the new SMTP object and then we enable StartTLS if necessary (this allows you to send email through SMTP hosts that require SSL connections).  Next we login to the SMTP server (with the &lt;code&gt;start&lt;/code&gt; command) and call &lt;code&gt;sendmail&lt;/code&gt; inside the block to do the actual delivery.  &lt;/p&gt;

&lt;p&gt;We&amp;#8217;re done.  That&amp;#8217;s how an email gets sent in Rails.  Next week we will create a quick monkey patch for ActionMailer based on the information that we learned from the trek.&lt;/p&gt;


</description>
      <pubDate>Mon, 14 Dec 2009 12:54:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:a6a6693d-ab06-4635-8b2c-fa3af2a3cffb</guid>
      <author>jake</author>
      <link>http://blog.flvorful.com/articles/2009/12/14/deep-in-rails-actionmailer-deliver-part-v</link>
      <category>Rails</category>
      <category>rails</category>
      <category>action_mailer</category>
      <category>deep</category>
      <category>DIR</category>
      <category>part4</category>
    </item>
    <item>
      <title>Deep in Rails: ActionMailer#deliver Part IV</title>
      <description>
&lt;p&gt;So we just opened up &lt;code&gt;CompiledTemplates&lt;/code&gt; and defined (or compiled) our unique method for this particular template.  Now we continue with &lt;code&gt;render&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# (line 193 action_pack/action_view/renderable.rb)
def render(view, local_assigns = {})
  compile(local_assigns)

  view.with_template self do
    view.send(:_evaluate_assigns_and_ivars)
    view.send(:_set_controller_content_type, mime_type) if respond_to?(:mime_type)

    view.send(method_name(local_assigns), local_assigns) do |*names|
      ivar = :@_proc_for_layout
      if !view.instance_variable_defined?(:"@content_for_#{names.first}") &amp;&amp; view.instance_variable_defined?(ivar) &amp;&amp; (proc = view.instance_variable_get(ivar))
        view.capture(*names, &amp;proc)
      elsif view.instance_variable_defined?(ivar = :"@content_for_#{names.first || :layout}")
        view.instance_variable_get(ivar)
      end
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and our params:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;view =&gt; #&lt;ActionView::Base:0x348189c 
          @template_format=:html, 
          @assigns={:message=&gt;"Send this message"}, 
          @helpers=#&lt;ActionView::Base::ProxyModule:0x3481810&gt;, 
          @controller=#&lt;MessageMailer:0x34904a0 
              @action_name="contact_form", 
              @subject="Im contacting you", 
              @content_type="text/plain", 
              @implicit_parts_order=["text/html", "text/enriched", "text/plain"], 
              @from="jake@somewhere.com", 
              @sent_on=Fri Nov 13 17:49:58 -0600 2009, 
              @headers={},
              @default_template_name="contact_form", 
              @mime_version="1.0", 
              @body={:message=&gt;"Send this message"}, 
              @mailer_name="message_mailer", 
              @recipients="someemail@somedomain.com", 
              @parts=[], 
              @template=#&lt;ActionView::Base:0x348189c ...&gt;, 
              @charset="utf-8"&gt;, 
          @_current_render=nil, 
          @assigns_added=nil, 
          @_first_render=nil, 
          @view_paths=["/example_app/app/views"]&gt;
local_assigns =&gt; {}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The first thing we do after we compile our unique method is call &lt;code&gt;with_template&lt;/code&gt; on &lt;code&gt;view&lt;/code&gt; which is a convenient method that allows us to temporarily swap out the current template for the view, set it to another one, do some processing and then return the original template back to the view.  Let&#8217;s see &lt;code&gt;with_template&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# (line 298 action_pack/action_view/base.rb)
def with_template(current_template)
  last_template, self.template = template, current_template
  yield
ensure
  self.template = last_template
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Quite simple indeed.  Now let&#8217;s see exactly what we are doing to the template.  The first thing we do is send the method &lt;code&gt;_evaluate_assigns_and_ivars&lt;/code&gt; to the view.  This is private method in ActionView::Base which creates instance variables for each key in the &lt;code&gt;`assigns@ attribute hash.  This hash is filled with our&lt;/code&gt;body&lt;code&gt;call in the mailer model you create.  Here is&lt;/code&gt;&lt;em&gt;evaluate&lt;/em&gt;assigns&lt;em&gt;and&lt;/em&gt;ivars`:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# (line 307 action_pack/action_view/base.rb)
def _evaluate_assigns_and_ivars #:nodoc:
 unless @assigns_added
   @assigns.each { |key, value| instance_variable_set("@#{key}", value) }
   _copy_ivars_from_controller
   @assigns_added = true
 end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;After the instance variables are set, we call &lt;code&gt;_copy_ivars_from_controller&lt;/code&gt; which does exactly that, copies the instance variables from this view&#8217;s controller to this view.  This is how instance variables that you create in normal controller methods are accessed in the view.  Let&#8217;s look at that definition:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# (line 315 action_pack/action_view/base.rb)
def _copy_ivars_from_controller #:nodoc:
  if @controller
    variables = @controller.instance_variable_names
    variables -= @controller.protected_instance_variables if @controller.respond_to?(:protected_instance_variables)
    variables.each { |name| instance_variable_set(name, @controller.instance_variable_get(name)) }
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This method finds all proper instance variables in the attached controller and sets the same instance variables in the current view object.  Once we have copied the instance variables we move to the next line in &lt;code&gt;render&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;view.send(:_set_controller_content_type, mime_type) if respond_to?(:mime_type)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is another private method in &lt;code&gt;ActionView::Base&lt;/code&gt; and it&#8217;s job is quite simple: set the content_type for the response attribute if this view&#8217;s controller has one.  Let&#8217;s look at the code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# (line 323 action_pack/action_view/base.rb)
def _set_controller_content_type(content_type) #:nodoc:
  if controller.respond_to?(:response)
    controller.response.content_type ||= content_type
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In our case, the controller is the &lt;code&gt;MessageMailer&lt;/code&gt; object and it doesnt respond to &lt;code&gt;response&lt;/code&gt; so we dont set a content_type.  Now we come back to &lt;code&gt;render&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# (line 193 action_pack/action_view/renderable.rb)
def render(view, local_assigns = {})
  ...
  view.with_template self do
    ...
    view.send(method_name(local_assigns), local_assigns) do |*names|
      ivar = :@_proc_for_layout
      if !view.instance_variable_defined?(:"@content_for_#{names.first}") &amp;&amp; view.instance_variable_defined?(ivar) &amp;&amp; (proc = view.instance_variable_get(ivar))
        view.capture(*names, &amp;proc)
      elsif view.instance_variable_defined?(ivar = :"@content_for_#{names.first || :layout}")
        view.instance_variable_get(ivar)
      end
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The next thing we are going to do is call our dynamically generated (and now compiled) view method for this template.  We call it with a block that is used to capture content pieces that this view may use (think &lt;code&gt;content_for&lt;/code&gt;).  AM does not use any of these so we end up skipping over this whole section and just executing our template method.  In a future series on &lt;code&gt;ActionController&lt;/code&gt;, we will dive more into what the block does and how Rails uses it&#8217;s information, but for now we will move on.&lt;/p&gt;

&lt;p&gt;So what exactly did we do when we called that dynamically generated method?  Let&#8217;s find out.  First, we will look at our method again:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def _run_erb_app47views47message_mailer47contact_form46erb(local_assigns)
        old_output_buffer = output_buffer;;@output_buffer = '';  __in_erb_template=true ; @output_buffer.concat "Hi,\n"
@output_buffer.concat "\n"
@output_buffer.concat "I am contacting you with this message:\n"
@output_buffer.concat "\n"
@output_buffer.concat(( @message ).to_s); @output_buffer.concat "\n"
@output_buffer.concat "\n"
@output_buffer.concat "\n"
@output_buffer.concat "\n"@output_buffer.concat "Thanks\n"
@output_buffer.concat "\n"
@output_buffer.concat "Jake"; @output_buffer
ensure
  self.output_buffer = old_output_buffer
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Remember that &lt;code&gt;output_buffer&lt;/code&gt; is an attribute inside of &lt;code&gt;ActionView::Base&lt;/code&gt; and that it holds the current output for the view that is being processed.  Our dynamic method first stores the current &lt;code&gt;output_buffer&lt;/code&gt; and then resets it so that it can insert the newly parsed message.  When we execute our method, we &lt;code&gt;concat&lt;/code&gt; our entire view (with any ruby processing) into the &lt;code&gt;output_buffer&lt;/code&gt;. So after we execute &lt;code&gt;_run_erb_app47views47message_mailer47contact_form46erb&lt;/code&gt; our output_buffer buffer looks like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@output_buffer =&gt; "Hi,\n\nI am contacting you with this message:\n\nSend this message\n\n\n\nThanks\n\nJake"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;which is the final email body that will be sent. &lt;/p&gt;

&lt;p&gt;Alright, now we have rendered our message and we hit the bottom of this method chain.  We now pop  all the way back up &lt;code&gt;create!&lt;/code&gt;. I know, I know. It was so long ago that you dont remember.  Here is a refresher:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(line 458 action_mailer/base.rb)
def create!(method_name, *parameters) #:nodoc:
  unless String === @body
    ...
    @body = render_message(@template, @body) if template_exists

    if !@parts.empty? &amp;&amp; String === @body
      @parts.unshift Part.new(:charset =&gt; charset, :body =&gt; @body)
      @body = nil
    end
  end

  @mime_version ||= "1.0" if !@parts.empty?

  @mail = create_mail
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We just got through with &lt;code&gt;render_message&lt;/code&gt; and now we have our &lt;code&gt;@body&lt;/code&gt; attribute filled with our message.  The next line checks to see if we have parts and if we have a body that&#8217;s a String.  If we do, we create a new Part with the current &lt;code&gt;@body&lt;/code&gt; and add it to all of our parts.  After that, we get rid of &lt;code&gt;@body&lt;/code&gt;.  We do this so that &lt;code&gt;create_mail&lt;/code&gt; doesnt try and rerender the body again if we have other parts.  Since we dont, we skip over this and go straight to:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@mail = create_mail
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we&#8217;re gettin&#8217; somewhere.  This starts the actual email processing part of AM.  Let&#8217;s see &lt;code&gt;create_mail&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(line 638 action_mailer/base.rb)
def create_mail
  m = TMail::Mail.new

  m.subject,     = quote_any_if_necessary(charset, subject)
  m.to, m.from   = quote_any_address_if_necessary(charset, recipients, from)
  m.bcc          = quote_address_if_necessary(bcc, charset) unless bcc.nil?
  m.cc           = quote_address_if_necessary(cc, charset) unless cc.nil?
  m.reply_to     = quote_address_if_necessary(reply_to, charset) unless reply_to.nil?
  m.mime_version = mime_version unless mime_version.nil?
  m.date         = sent_on.to_time rescue sent_on if sent_on

  headers.each { |k, v| m[k] = v }

  real_content_type, ctype_attrs = parse_content_type

  if @parts.empty?
    m.set_content_type(real_content_type, nil, ctype_attrs)
    m.body = normalize_new_lines(body)
  else
    if String === body
      part = TMail::Mail.new
      part.body = normalize_new_lines(body)
      part.set_content_type(real_content_type, nil, ctype_attrs)
      part.set_content_disposition "inline"
      m.parts &lt;&lt; part
    end

    @parts.each do |p|
      part = (TMail::Mail === p ? p : p.to_mail(self))
      m.parts &lt;&lt; part
    end

    if real_content_type =~ /multipart/
      ctype_attrs.delete "charset"
      m.set_content_type(real_content_type, nil, ctype_attrs)
    end
  end

  @mail = m
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The first thing we do is initialize a new &lt;code&gt;TMail::Mail&lt;/code&gt; instance and then we go on to assign several attributes for it.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;m.subject,     = quote_any_if_necessary(charset, subject)
m.to, m.from   = quote_any_address_if_necessary(charset, recipients, from)
m.bcc          = quote_address_if_necessary(bcc, charset) unless bcc.nil?
m.cc           = quote_address_if_necessary(cc, charset) unless cc.nil?
m.reply_to     = quote_address_if_necessary(reply_to, charset) unless reply_to.nil?
m.mime_version = mime_version unless mime_version.nil?
m.date         = sent_on.to_time rescue sent_on if sent_on
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;quote_any_if_necessary&lt;/code&gt;, &lt;code&gt;quote_any_address_if_necessary&lt;/code&gt; and &lt;code&gt;quote_address_if_necessary&lt;/code&gt; are helper methods included from the module &lt;code&gt;ActionMailer::Quoting&lt;/code&gt;.  Let&#8217;s take a gander at those methods:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(line 5 action_mailer/quoting.rb)

def quoted_printable(text, charset)
  text = text.gsub( /[^a-z ]/i ) { quoted_printable_encode($&amp;) }.gsub( / /, "_" )
  "=?#{charset}?Q?#{text}?="
end

def quoted_printable_encode(character)
  result = ""
  character.each_byte { |b| result &lt;&lt; "=%02X" % b }
  result
end

if !defined?(CHARS_NEEDING_QUOTING)
  CHARS_NEEDING_QUOTING = /[\000-\011\013\014\016-\037\177-\377]/
end

def quote_if_necessary(text, charset)
  text = text.dup.force_encoding(Encoding::ASCII_8BIT) if text.respond_to?(:force_encoding)

  (text =~ CHARS_NEEDING_QUOTING) ?
    quoted_printable(text, charset) :
    text
end

def quote_any_if_necessary(charset, *args)
  args.map { |v| quote_if_necessary(v, charset) }
end

def quote_address_if_necessary(address, charset)
  if Array === address
    address.map { |a| quote_address_if_necessary(a, charset) }
  elsif address =~ /^(\S.*)\s+(&lt;.*&gt;)$/
    address = $2
    phrase = quote_if_necessary($1.gsub(/^['"](.*)['"]$/, '\1'), charset)
    "\"#{phrase}\" #{address}"
  else
    address
  end
end

def quote_any_address_if_necessary(charset, *args)
  args.map { |v| quote_address_if_necessary(v, charset) }
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Im not going to bore you with the inane details, needless to say, these methods take illegal characters and quote them if necessary.  Once these are quoted and sanitized, they are inserted into the Mail object.  After we initialize those attributes, we set the header attributes for the Mail object with the following line:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;headers.each { |k, v| m[k] = v }

real_content_type, ctype_attrs = parse_content_type
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We cycle through all the headers of our mailer object and stick them into the TMail::Mail object.  Next we call &lt;code&gt;parse_content_type&lt;/code&gt; which is a private method that we get from &lt;code&gt;ActionMailer::PartContainer&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(line 43 action_mailer/part_container.rb)
def parse_content_type(defaults=nil)
  if content_type.blank? 
    return defaults ? 
      [ defaults.content_type, { 'charset' =&gt; defaults.charset } ] : 
      [ nil, {} ] 
  end 
  ctype, *attrs = content_type.split(/;\s*/)
  attrs = attrs.inject({}) { |h,s| k,v = s.split(/=/, 2); h[k] = v; h }
  [ctype, {"charset" =&gt; charset || defaults &amp;&amp; defaults.charset}.merge(attrs)]
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;All we are doing here is parsing the content&lt;em&gt;type of the mailer (in our case &#8220;text/plain&#8221;) and returning an array with the content&lt;/em&gt;type and a hash.  Let&#8217;s see what our example ends up returning:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;parse_content_type =&gt; ["text/plain", {"charset"=&gt;"utf-8"}]
real_content_type =&gt; "text/plain"
ctype_attrs =&gt; {"charset"=&gt;"utf-8"}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we move on to: &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;if @parts.empty?
  m.set_content_type(real_content_type, nil, ctype_attrs)
  m.body = normalize_new_lines(body)
else
  ...
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In our case, &lt;code&gt;@parts&lt;/code&gt; is empty so we set the content type of our TMail object with the results from our parsing.  After that, we set the body of the TMail object to the current AM object&#8217;s body, but we first do some sanitation duties with &lt;code&gt;normalize_new_lines&lt;/code&gt; which is a method in ActionMailer::Utils.  In fact, it is the only method in that module:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(action_mailer/utils.rb)
module ActionMailer
  module Utils #:nodoc:
    def normalize_new_lines(text)
      text.to_s.gsub(/\r\n?/, "\n")
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What we are doing here is cleansing Microsoft evil from the message.  Windows likes to use &#8220;\r\n&#8221; for line breaks in text, the rest of computing thinks it&#8217;s enough to just use &#8220;\n&#8221;.  I agree with the rest of computing.  Anyway, this method changes all &#8220;\r\n&#8220;&#8216;s to &#8220;\n&#8220;&#8216;s so that our email message parses correctly on all email servers.&lt;/p&gt;

&lt;p&gt;After we normalize, we are done with setting up the object and the final line of &lt;code&gt;create_mail&lt;/code&gt; is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@mail = m
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we set the AM attribute &lt;code&gt;@mail&lt;/code&gt; to the newly instantiated TMail object and we&#8217;re done&#8230; with the creation of the email message.  Now we have to actually send it.  We&#8217;ll get to that next.  See ya then.&lt;/p&gt;



</description>
      <pubDate>Sun, 06 Dec 2009 09:42:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:a95502ca-484a-400f-b3dc-182d1db922ab</guid>
      <author>jake</author>
      <link>http://blog.flvorful.com/articles/2009/12/06/deep-in-rails-actionmailer-deliver-part-iv</link>
      <category>Rails</category>
      <category>rails</category>
      <category>action_mailer</category>
      <category>deep</category>
      <category>DIR</category>
      <category>part4</category>
    </item>
    <item>
      <title>Deep in Rails: ActionMailer#deliver Part III</title>
      <description>&lt;p&gt;When we last left off we were just about to jump into &lt;code&gt;Renderable#render&lt;/code&gt;.  That&#8217;s where we are going next:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# (line 193 action_pack/action_view/renderable.rb)
def render(view, local_assigns = {})
  compile(local_assigns)

  view.with_template self do
    view.send(:_evaluate_assigns_and_ivars)
    view.send(:_set_controller_content_type, mime_type) if respond_to?(:mime_type)

    view.send(method_name(local_assigns), local_assigns) do |*names|
      ivar = :@_proc_for_layout
      if !view.instance_variable_defined?(:"@content_for_#{names.first}") &amp;&amp; view.instance_variable_defined?(ivar) &amp;&amp; (proc = view.instance_variable_get(ivar))
        view.capture(*names, &amp;proc)
      elsif view.instance_variable_defined?(ivar = :"@content_for_#{names.first || :layout}")
        view.instance_variable_get(ivar)
      end
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Alright, this is where we get real deep into Rails.  This particular method does the vast majority of the rendering work in Rails.  Let&#8217;s see what&#8217;s going on:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;compile(local_assigns)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is the first line and it sets up a series of methods that we are going to run through. &lt;code&gt;compile&lt;/code&gt; is a private method in &lt;code&gt;Renderable&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# (line 193 action_pack/action_view/renderable.rb)
def compile(local_assigns)
  render_symbol = method_name(local_assigns)

  if !Base::CompiledTemplates.method_defined?(render_symbol) || recompile?
    compile!(render_symbol, local_assigns)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;which starts out creating a method symbol for this renderable object by calling another private method aptly named &lt;code&gt;method_name&lt;/code&gt;.  This is the definition for &lt;code&gt;method_name&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# (line 45 action_pack/action_view/renderable.rb)
def method_name(local_assigns)
  if local_assigns &amp;&amp; local_assigns.any?
    method_name = method_name_without_locals.dup
    method_name &lt;&lt; "_locals_#{local_assigns.keys.map { |k| k.to_s }.sort.join('_')}"
  else
    method_name = method_name_without_locals
  end
  method_name.to_sym
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here are the params for our example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;local_assigns =&gt; {}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Since our &lt;code&gt;local_assigns&lt;/code&gt; is empty, we end up executing the else part of the conditional which sets &lt;code&gt;method_name&lt;/code&gt; to the result &lt;code&gt;method_name_without_locals&lt;/code&gt; which is yet another private method in &lt;code&gt;Renderable&lt;/code&gt;.  Here it is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# (line 22 action_pack/action_view/renderable.rb)
def method_name_without_locals
  ['_run', extension, method_segment].compact.join('_')
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This method gives us unique method name to use for the definition of the compiled rendered template.  You may have seen something like the following in your Rails development logs:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Account Columns (251.9ms)   SHOW FIELDS FROM `accounts`
AccountSettings Columns (4.2ms)   SHOW FIELDS FROM `account_settings`
Account Load (0.5ms)   SELECT * FROM `accounts` WHERE (`accounts`.`id` = 47715) 
  app/controllers/application.rb:144:in `current_user'
  app/views/layouts/bare.rhtml:21:in `_run_rhtml_app47views47layouts47bare46rhtml'
  app/controllers/administration_controller.rb:10:in `index'
  vendor/plugins/mongrel_proctitle/lib/mongrel_proctitle.rb:114:in `process_client'
  vendor/plugins/mongrel_proctitle/lib/mongrel_proctitle.rb:33:in `request'
  vendor/plugins/mongrel_proctitle/lib/mongrel_proctitle.rb:112:in `process_client'
  vendor/plugins/mongrel_proctitle/lib/mongrel_proctitle.rb:102:in `run'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You see that line:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;app/views/layouts/bare.rhtml:21:in `_run_rhtml_app47views47layouts47bare46rhtml'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;the &lt;code&gt;_run_rhtml_app47views47layouts47bare46rhtml&lt;/code&gt; is actually the name of the method that is given to your template.  This is done because Rails &lt;em&gt;executes&lt;/em&gt; your template, just like any piece of Ruby code.  To do that, it needs a method name, and that is what we are doing in the &lt;code&gt;method_name_without_locals&lt;/code&gt; method, creating a unique method name for this template we are about to run. &lt;code&gt;method_segment&lt;/code&gt; is a method that is included in from &lt;code&gt;ActionView::Template&lt;/code&gt; and &lt;code&gt;extension&lt;/code&gt; is an attribute in &lt;code&gt;ActionView::Template&lt;/code&gt;.  Here is &lt;code&gt;method_segment&lt;/code&gt; and &lt;code&gt;extension&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# (line 22 action_pack/action_view/template.rb)
def method_segment
  relative_path.to_s.gsub(/([^a-zA-Z0-9_])/) { $1.ord }
end

extension =&gt; "erb"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;which calls another method in &lt;code&gt;Template&lt;/code&gt; called &lt;code&gt;relative_path&lt;/code&gt; displayed here:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# (line 172 action_pack/action_view/template.rb)
def relative_path
  path = File.expand_path(filename)
  path.sub!(/^#{Regexp.escape(File.expand_path(RAILS_ROOT))}\//, '') if defined?(RAILS_ROOT)
  path
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;First, we get the full pathname to the current template and then we run &lt;code&gt;sub&lt;/code&gt; on the path to remove anything that may look like the full expanded path of &lt;code&gt;RAILS_ROOT&lt;/code&gt; if &lt;code&gt;RAILS_ROOT&lt;/code&gt; is defined.  The template&#8217;s filename is stored in the attribute &lt;code&gt;filename&lt;/code&gt;.  Here are the params:&lt;/p&gt;

&lt;pre id="scroll_to_here" &gt;&lt;code&gt;path =&gt; app/views/message_mailer/contact_form.erb
filename =&gt; /example_app/app/views/message_mailer/contact_form.erb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see, the main purpose for this method is to give us the relative path to the mailer.  Now that we got our path, let&#8217;s see what &lt;code&gt;method_segment&lt;/code&gt; does to it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;relative_path.to_s.gsub(/([^a-zA-Z0-9_])/) { $1.ord }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We call &lt;code&gt;gsub&lt;/code&gt; on the path, using the less familiar block usage.  This particular usage passes each matched string to the block for processing.  In this case, we want to match any character that isnt alphanumeric or an &#8220;_&#8221;.  We take each of these matches (which are the individual characters that matched our expression) and call &lt;code&gt;ord&lt;/code&gt; on them which returns their ASCII number.  So in our case,  &lt;code&gt;method_segment&lt;/code&gt; would end up returning &lt;code&gt;app47views47message_mailer47contact_form46erb&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Good, now we have our method_segment and we know what our extension is, so let&#8217;s see what we get from &lt;code&gt;method_name_without_locals&lt;/code&gt; for our example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;_run_erb_app47views47message_mailer47contact_form46erb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Whew, now we&#8217;re back to &lt;code&gt;Renderable#method_name&lt;/code&gt; with our method name and we return back from that  to &lt;code&gt;compile&lt;/code&gt;.  Let&#8217;s refresh our memories real quick:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# (line 193 action_pack/action_view/renderable.rb)
def compile(local_assigns)
  render_symbol = method_name(local_assigns)

  if !Base::CompiledTemplates.method_defined?(render_symbol) || recompile?
    compile!(render_symbol, local_assigns)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and we get back for &lt;code&gt;render_symbol&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:_run_erb_app47views47message_mailer47contact_form46erb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The next section is where the super-crazy-secret-sauce magic happens, but first we have to do some checks.  First, we check to see if our &lt;code&gt;render_symbol&lt;/code&gt; is defined as a method in the module &lt;code&gt;ActionView::Base::CompiledTemplates&lt;/code&gt;.  Let&#8217;s take a gander at CompiledTemplates:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# (line 193 action_pack/action_view/renderable.rb)
module CompiledTemplates #:nodoc:
  # holds compiled template code
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What the&#8230;.  Where is the code?  &lt;/p&gt;

&lt;p&gt;Well, remember that we just created a new method name for our template.  Why did we do that?  Because Rails needs to execute the template as with everything else.  So we have to define the method somehow so that it can be executed, right?  Exactly.  That is what &lt;code&gt;CompiledTemplates&lt;/code&gt; is for.  It&#8217;s the placeholder module where we will keep these method definitions.  Basically, it&#8217;s a nice container to hold these dynamically created methods so they arent spread out all over &lt;code&gt;ObjectSpace&lt;/code&gt;.  Plus, it makes clearing the methods cache pretty simple, just undef every method in &lt;code&gt;CompiledTemplates&lt;/code&gt;.  So first, we check to see if there is a method defined for this particular template.  Then we check the private method &lt;code&gt;recompile?&lt;/code&gt;, which is so simple, that I think it may be a placeholder for something in the future.  Here is &lt;code&gt;recompile?&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# (line 92 action_pack/action_view/renderable.rb)
def recompile?
  false
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So basically, we are just checking the first part of our condition for the method definition.  In our case, we dont have a method defined as such and we go on to &lt;code&gt;compile!&lt;/code&gt;, which is a private method in &lt;code&gt;Renderable&lt;/code&gt; and looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# (line 66 action_pack/action_view/renderable.rb)
def compile!(render_symbol, local_assigns)
  locals_code = local_assigns.keys.map { |key| "#{key} = local_assigns[:#{key}];" }.join

  source = &lt;&lt;-end_src
    def #{render_symbol}(local_assigns)
      old_output_buffer = output_buffer;#{locals_code};#{compiled_source}
    ensure
      self.output_buffer = old_output_buffer
    end
  end_src

  begin
    ActionView::Base::CompiledTemplates.module_eval(source, filename, 0)
  rescue Errno::ENOENT =&gt; e
    raise e # Missing template file, re-raise for Base to rescue
  rescue Exception =&gt; e # errors from template code
    if logger = defined?(ActionController) &amp;&amp; Base.logger
      logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}"
      logger.debug "Function body: #{source}"
      logger.debug "Backtrace: #{e.backtrace.join("\n")}"
    end

    raise ActionView::TemplateError.new(self, {}, e)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here, we start by creating the string that will assign the local variables to their proper values and storing it in the variable &lt;code&gt;locals_code&lt;/code&gt;.  Then we move on to creating the source code that we want dynamically created and inserted into &lt;code&gt;CompiledTemplates&lt;/code&gt;.  This code uses the method &lt;code&gt;compiled_source&lt;/code&gt; which uses another method named &lt;code&gt;handler&lt;/code&gt;. &lt;code&gt;handler&lt;/code&gt; is a wrapper method for &lt;code&gt;handler_class_for_extension&lt;/code&gt; which is a class method belonging to &lt;code&gt;Template&lt;/code&gt;.  This method is defined in &lt;code&gt;TemplateHandlers&lt;/code&gt; and extended by &lt;code&gt;Template&lt;/code&gt;. All of these methods are illustrated below:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# (line 66 action_pack/action_view/renderable.rb)
def handler
  Template.handler_class_for_extension(extension)
end

def compiled_source
  handler.call(self)
end

# (action_pack/action_view/template_handlers_.rb)
module ActionView #:nodoc:
  module TemplateHandlers #:nodoc:
    ...
    def self.extended(base)
      base.register_default_template_handler :erb, TemplateHandlers::ERB
      base.register_template_handler :rjs, TemplateHandlers::RJS
      base.register_template_handler :builder, TemplateHandlers::Builder

      base.register_template_handler :rhtml, TemplateHandlers::ERB
      base.register_template_handler :rxml, TemplateHandlers::Builder
    end
    ...
    def registered_template_handler(extension)
      extension &amp;&amp; ``template_handlers[extension.to_sym]
    end
    ...
    def handler_class_for_extension(extension)
      registered_template_handler(extension) || ``default_template_handlers
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When &lt;code&gt;TemplateHandlers&lt;/code&gt; is extended it registers several extension handlers.  You are probably familiar with all of them, so we wont go into what each extension is for.  &lt;code&gt;handler_class_for_extension&lt;/code&gt; returns the result of &lt;code&gt;registered_template_handler&lt;/code&gt; or &lt;code&gt;@default_template_handlers&lt;/code&gt;. &lt;code&gt;registered_template_handler&lt;/code&gt; returns the proper handler (TemplateHandlers::ERB, TemplateHandlers::RJS or TemplateHandlers::MyCustomTemplateHandler) from the class variable &lt;code&gt;@template_handlers&lt;/code&gt; which holds the defaults plus any newly registered templates.  &lt;/p&gt;

&lt;p&gt;So we get the proper handler back (in our case &lt;code&gt;ActionView::TemplateHandlers::ERB&lt;/code&gt;) and we execute the &lt;code&gt;call&lt;/code&gt; method with our &lt;code&gt;ReloadableTemplate&lt;/code&gt; as the parameter.  &lt;code&gt;call&lt;/code&gt; is a class method in the module &lt;code&gt;TemplateHandlers::Compilable&lt;/code&gt; and included into &lt;code&gt;ERB&lt;/code&gt;. It looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# (line 4 action_pack/action_view/template_handlers_.rb)
module Compilable
  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods
    def call(template)
      new.compile(template)
    end
  end

  def compile(template)
    raise "Need to implement #{self.class.name}#compile(template)"
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When we include this module we extend the base class with the module &lt;code&gt;ClassMethods&lt;/code&gt; which contains the &lt;code&gt;call&lt;/code&gt; method.  This method creates a new instance of the base class and calls the &lt;code&gt;compile&lt;/code&gt; instance method with the template.  The &lt;code&gt;compile&lt;/code&gt; in this module raises an error to let you know that it is an abstract method and needs to be defined by the base class, in our case &lt;code&gt;ERB&lt;/code&gt;.  Let&#8217;s see what &lt;code&gt;ERB&lt;/code&gt; looks like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# (line 4 action_pack/action_view/template_handlers/erb.rb)
class ERB &lt; TemplateHandler
  include Compilable

  cattr_accessor :erb_trim_mode
  self.erb_trim_mode = '-'
  ...
  def compile(template)
    src = ::ERB.new("&lt;% __in_erb_template=true %&gt;#{template.source}", nil, erb_trim_mode, '@output_buffer').src
    RUBY_VERSION &gt;= '1.9' ? src.sub(/\A#coding:.*\n/, '') : src
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;compile&lt;/code&gt; is pretty simple.  We create a new instance of ERB parser and pass it the template source and the variable that we want to build the output on (&lt;code&gt;@output_buffer&lt;/code&gt;) and returning the &lt;code&gt;src&lt;/code&gt; attribute which holds the ruby code generated by the ERB parser. &lt;code&gt;@output_buffer&lt;/code&gt; is the name of an attribute inside of &lt;code&gt;ActionView::Base&lt;/code&gt; that is used as the output buffer (of course) which will get flushed when we do the final rendering (towards the end of the deliver method). In the case of an AM view, the rendering is pretty simple, but when we get to full controller views with partials we need a place to concat all the different views together which is what we use &lt;code&gt;@output_buffer&lt;/code&gt; for. The next line checks for Ruby 1.9 and does some cleaning of the result before returning it.  Here is what &lt;code&gt;src&lt;/code&gt; outputs for our example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;src =&gt; "@output_buffer = '';  __in_erb_template=true ; @output_buffer.concat \"Hi,\\n\"\n@output_buffer.concat \"\\n\"\n@output_buffer.concat \"I am contacting you with this message:\\n\"\n@output_buffer.concat \"\\n\"\n@output_buffer.concat(( `message ).to_s); @output_buffer.concat \"\\n\"\n@output_buffer.concat \"\\n\"\n@output_buffer.concat \"\\n\"\n@output_buffer.concat \"\\n\"\n@output_buffer.concat \"Thanks\\n\"\n@output_buffer.concat \"\\n\"\n@output_buffer.concat \"Jake\"; @output_buffer"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is one long string that represents the compiled version of the ruby code for our mailer view.  Now that we have the compiled_source, let&#8217;s go back &lt;code&gt;compile!&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# (line 66 action_pack/action_view/renderable.rb)
def compile!(render_symbol, local_assigns)
  locals_code = local_assigns.keys.map { |key| "#{key} = local_assigns[:#{key}];" }.join

  source = &lt;&lt;-end_src
    def #{render_symbol}(local_assigns)
      old_output_buffer = output_buffer;#{locals_code};#{compiled_source}
    ensure
      self.output_buffer = old_output_buffer
    end
  end_src
  ...
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So now we know what all the pieces mean, let&#8217;s see what our example becomes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def _run_erb_app47views47message_mailer47contact_form46erb(local_assigns)
  old_output_buffer = output_buffer;;@output_buffer = '';  __in_erb_template=true ; @output_buffer.concat "Hi,\n"
  @output_buffer.concat "\n"
  @output_buffer.concat "I am contacting you with this message:\n"
  @output_buffer.concat "\n"
  @output_buffer.concat(( `message ).to_s); @output_buffer.concat "\n"
  @output_buffer.concat "\n"
  @output_buffer.concat "\n"
  @output_buffer.concat "\n"@output_buffer.concat "Thanks\n"
  @output_buffer.concat "\n"
  @output_buffer.concat "Jake"; @output_buffer
ensure
  self.output_buffer = old_output_buffer
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Alright, now we got the code we want eval&#8217;ed, let&#8217;s keep going through &lt;code&gt;compile!&lt;/code&gt; &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# (line 66 action_pack/action_view/renderable.rb)
def compile!(render_symbol, local_assigns)
  ...
  begin
    ActionView::Base::CompiledTemplates.module_eval(source, filename, 0)
  rescue Errno::ENOENT =&gt; e
    raise e # Missing template file, re-raise for Base to rescue
  rescue Exception =&gt; e # errors from template code
    if logger = defined?(ActionController) &amp;&amp; Base.logger
      logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}"
      logger.debug "Function body: #{source}"
      logger.debug "Backtrace: #{e.backtrace.join("\n")}"
    end

    raise ActionView::TemplateError.new(self, {}, e)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we open up &lt;code&gt;CompiledTemplates&lt;/code&gt; and perform a &lt;code&gt;module_eval&lt;/code&gt; with the source we just made and the filename of this template (&lt;code&gt;/example_app/app/views/message_mailer/contact_form.erb&lt;/code&gt;) and &lt;code&gt;0&lt;/code&gt;.  The filename and the number 0 are used in error reporting during &lt;code&gt;module_eval&lt;/code&gt;.  Let&#8217;s say something went wrong with the module_eval, in our case, the error would look something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/example_app/app/views/message_mailer/contact_form.erb:0:in `module_eval': the real problem goes here
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&#8217;s it for this week.  Next week we continue with our dynamically compiled method and see what Rails does with it.&lt;/p&gt;


</description>
      <pubDate>Sun, 29 Nov 2009 10:47:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:df11f064-42eb-4a46-a7d3-79cde9d0236b</guid>
      <author>jake</author>
      <link>http://blog.flvorful.com/articles/2009/11/29/deep-in-rails-actionmailer-deliver-part-iii</link>
      <category>Rails</category>
      <category>rails</category>
      <category>action_mailer</category>
      <category>deep</category>
      <category>DIR</category>
      <category>part3</category>
    </item>
    <item>
      <title>Deep in Rails: ActionMailer#deliver Part II</title>
      <description>&lt;p&gt;When we left off &lt;a href="http://blog.flvorful.com/articles/2009/11/15/deep-in-rails-actionmailer-deliver-part-i"&gt;last&lt;/a&gt;, we were just about to get into rendering the message.  Let&#8217;s recap that code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(line 553 action_mailer/base.rb)
def render_message(method_name, body)
  if method_name.respond_to?(:content_type)
    @current_template_content_type = method_name.content_type
  end
  render :file =&amp;gt; method_name, :body =&amp;gt; body
ensure
  @current_template_content_type = nil
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When we call &lt;code&gt;render_message&lt;/code&gt; in &lt;code&gt;create!&lt;/code&gt;, we call it with &lt;code&gt;@template&lt;/code&gt; and &lt;code&gt;@body&lt;/code&gt;, let&#8217;s see what those get set to inside of &lt;code&gt;render_message&lt;/code&gt; for our example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@template   = method_name     =&amp;gt; "contact_form" 
@body       = body            =&amp;gt; {:message=&amp;gt;"Send this message"}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At the beginning of render_message &lt;code&gt;@body&lt;/code&gt; is set to the hash of instance variables that we set in our &lt;code&gt;contact_form&lt;/code&gt; method in our mailer.  Once we are finished processing, that hash will be gone and &lt;code&gt;@body&lt;/code&gt; will be replaced with the full rendered message.&lt;/p&gt;
&lt;p&gt;Next, we see that we want to set the &lt;code&gt;@current_template_content_type&lt;/code&gt; instance variable to the proper content type.  This is mainly used for multipart so that if render is passed one of those fancy &lt;code&gt;ActionView::ReloadableTemplate&lt;/code&gt; objects it renders it with the proper parser. Since we did not specify a content_type the method_name &#8220;contact_form&#8221; is passed and we get to skip over that part and go straight to the meat:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;render :file =&amp;gt; method_name, :body =&amp;gt; body&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is not the same render from &lt;code&gt;ActionController&lt;/code&gt; or &lt;code&gt;ActionView&lt;/code&gt;, but it does use the AV template render methods.  Let&#8217;s take a look at the definition:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(line 562 action_mailer/base.rb)
def render(opts)
  body = opts.delete(:body)
  if opts[:file] &amp;#38;&amp;#38; (opts[:file] !~ /\// &amp;#38;&amp;#38; !opts[:file].respond_to?(:render))
    opts[:file] = "#{mailer_name}/#{opts[:file]}" 
  end

  begin
    old_template, @template = @template, initialize_template_class(body)
    layout = respond_to?(:pick_layout, true) ? pick_layout(opts) : false
    @template.render(opts.merge(:layout =&amp;gt; layout))
  ensure
    @template = old_template
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and the params with our example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;opts =&amp;gt; {
  :file =&amp;gt; "contact_form",
  :body =&amp;gt; {:message=&amp;gt;"Send this message"}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first thing we do is set the variable &lt;code&gt;body&lt;/code&gt; to &lt;code&gt;opts[:body]&lt;/code&gt; and delete it from the options hash (this is all done in one stroke by the call &lt;code&gt;delete&lt;/code&gt; which returns the value that was deleted).  Next, we test to see if &lt;code&gt;opts[:file]&lt;/code&gt; does not match &#8220;/&#8221; and does not respond to render then we set &lt;code&gt;opts[:file]&lt;/code&gt; to the same thing but prepended with the mailer_name, in our case &#8220;message_mailer&#8221;.&lt;/p&gt;
&lt;p&gt;Now we are getting to the real meat. First, we need to set some quick variables before we render.  Here are the 2 lines we will be examining next:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;old_template, @template = @template, initialize_template_class(body)
layout = respond_to?(:pick_layout, true) ? pick_layout(opts) : false&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the first line we are swapping out the current &lt;code&gt;@template&lt;/code&gt; variable with the result of &lt;code&gt;initialize_template_class(body)&lt;/code&gt; and storing the old value in &lt;code&gt;old_template&lt;/code&gt;.  Here is the definition of &lt;code&gt;initialize_template_class&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(line 603 action_mailer/base.rb)
def initialize_template_class(assigns)
  template = ActionView::Base.new(self.class.view_paths, assigns, self)
  template.template_format = default_template_format
  template
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and &lt;code&gt;assigns&lt;/code&gt; gets set to:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;body =&amp;gt; {:message=&amp;gt;"Send this message"}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first thing we see is that we create a var named &lt;code&gt;template&lt;/code&gt; that is a new instantiation of &lt;code&gt;ActionView::Base&lt;/code&gt; with the &lt;code&gt;view_paths&lt;/code&gt;, &lt;code&gt;assigns&lt;/code&gt;, and the &lt;code&gt;model&lt;/code&gt; (MessageMailer in our example) passed to it. Let&#8217;s dig in and cross over to &lt;code&gt;ActionView::Base&lt;/code&gt; and look at &lt;code&gt;initialize&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(line 221 action_pack/action_view/base.rb)
def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil)#:nodoc:
  @assigns = assigns_for_first_render
  @assigns_added = nil
  @controller = controller
  @helpers = ProxyModule.new(self)
  self.view_paths = view_paths
  @_first_render = nil
  @_current_render = nil
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and the params with our example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;view_paths               =&amp;gt; ["/example_app/app/views"]
assigns_for_first_render =&amp;gt; {:message=&amp;gt;"Send this message"}
controller               =&amp;gt; #&amp;lt;MessageMailer:0x34a579c 
                @action_name="contact_form", 
                @subject="Im contacting you", 
                @content_type="text/plain", 
                @implicit_parts_order=["text/html", "text/enriched", "text/plain"], 
                @from="jake@somewhere.com", 
                @sent_on=Sun Nov 08 11:34:17 -0600 2009, 
                @headers={}, 
                @default_template_name="contact_form", 
                @mime_version="1.0", 
                @body={:message=&amp;gt;"Send this message"}, 
                @mailer_name="message_mailer", 
                @recipients="someemail@somedomain.com", 
                @parts=[], 
                @template="contact_form", 
                @charset="utf-8"&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This allows us to wrap the mailers view around the &lt;code&gt;ActionView&lt;/code&gt; templating system and reuse the rendering module from &lt;code&gt;ActionView&lt;/code&gt; in AM. This also stores our body variables for use inside of our view. Now that we have a template, we need to initialize the &lt;code&gt;template_format&lt;/code&gt; with our mailer&#8217;s default template format.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;template.template_format = default_template_format&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&#8217;s open up the definition for default_template_format&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(line 577 action_mailer/base.rb)
def default_template_format
  if @current_template_content_type
    Mime::Type.lookup(@current_template_content_type).to_sym
  else
    :html
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This method checks the &lt;code&gt;@current_template_content_type&lt;/code&gt; ivar and returns the proper mime-type.  This is used as a switch by the renderer.  If you dont explicitly set the content type AM defaults to &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/span&gt; and your message is rendered in &lt;span class="caps"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/span&gt; mode.  Since we didnt define a &lt;code&gt;content_type&lt;/code&gt; in our example &lt;code&gt;@current_template_content_type&lt;/code&gt; is nil and :html will be returned for the &lt;code&gt;default_template_format&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;After that we return the created template instance and that gets us through the &lt;code&gt;initialize_template_class&lt;/code&gt; method.&lt;/p&gt;
&lt;p&gt;So now that we have set the &lt;code&gt;@template&lt;/code&gt; ivar in:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;old_template, @template = @template, initialize_template_class(body)
layout = respond_to?(:pick_layout, true) ? pick_layout(opts) : false&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We move down to setting the layout for the mailer.  In Rails you have the ability to use layouts just like in regular views. In our case, if we wanted to use a layout, we would have to add a file named &lt;code&gt;message_mailer.html.erb&lt;/code&gt; in &lt;code&gt;app/views/layouts&lt;/code&gt;.  The other option is specifying a layout name in our mailer model (just like we would in a controller).  So we could define MessageMailer as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class MessageMailer &amp;lt; ActionMailer::Base
  layout "my_email_layout" 
  def contact_form(msg_from, message)
    ...
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In that case, we would need a file named &lt;code&gt;my_email_layout.html.erb&lt;/code&gt; in our layouts directory.  Since we include &lt;code&gt;ActionController::Layout&lt;/code&gt; in AM::Base our model will respond to &lt;code&gt;pick_layout&lt;/code&gt;.  This is the method that will determine the layout needed for the renderer. Let&#8217;s dive into &lt;code&gt;pick_layout&lt;/code&gt;, which is defined in &lt;code&gt;ActionController::Layout&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# (line 229 action_pack/action_controller/layout.rb)
def pick_layout(options)
  if options.has_key?(:layout)
    case layout = options.delete(:layout)
    when FalseClass
      nil
    when NilClass, TrueClass
      active_layout if action_has_layout? &amp;#38;&amp;#38; candidate_for_layout?(:template =&amp;gt; default_template_name)
    else
      active_layout(layout, :html_fallback =&amp;gt; true)
    end
  else
    active_layout if action_has_layout? &amp;#38;&amp;#38; candidate_for_layout?(options)
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and the params for our example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;options =&amp;gt; {:file=&amp;gt;"message_mailer/contact_form"}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first part of &lt;code&gt;pick_layout&lt;/code&gt; checks for the key &lt;code&gt;:layout&lt;/code&gt; in options and since we didnt define it in our example we will skip over it and straight to the else part of the conditional:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;active_layout if action_has_layout? &amp;#38;&amp;#38; candidate_for_layout?(options)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, we call the method &lt;code&gt;active_layout&lt;/code&gt;  if action_has_layout? returns true and candidate_for_layout?(options) returns true.  &lt;code&gt;action_has_layout?&lt;/code&gt; is a simple method to check if this action or mailer method has a layout and is basically making sure that your :except and :only actions render properly.  Let&#8217;s take a look at action_has_layout? with our example&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# (line 244 action_pack/action_controller/layout.rb)
def action_has_layout?
  if conditions = self.class.layout_conditions
    case
      when only = conditions[:only]
        only.include?(action_name)
      when except = conditions[:except]
        !except.include?(action_name)
      else
        true
    end
  else
    true
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and &lt;code&gt;conditions&lt;/code&gt; would be:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;conditions =&amp;gt; nil&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since we are not setting a layout for our message the method &lt;code&gt;self.class.layout_conditions&lt;/code&gt; returns nil.  &lt;code&gt;layout_conditions&lt;/code&gt; is a class method on AM that reads the attribute accessor hash &lt;code&gt;layout_conditions&lt;/code&gt;.  These conditions are written when you make the call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;layout "my_template" # or layout "my_template", :except =&amp;gt; "some_message"&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This writes all your conditions to a attribute hash for easy reading and subclassing.  Since our example returns nil for &lt;code&gt;layout_conditions&lt;/code&gt; we end up at the outer else statement and return true out of this method and on to &lt;code&gt;candidate_for_layout?(options)&lt;/code&gt;.  This is a base method is written in layout.rb and overridden in AM::base.rb:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# (line 585 action_mailer/base.rb)
def candidate_for_layout?(options)
  !self.view_paths.find_template(default_template_name, default_template_format).exempt_from_layout?
rescue ActionView::MissingTemplate
  return true
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and our paramaters and extra variables/methods :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;options =&amp;gt; {:file=&amp;gt;"message_mailer/contact_form"}
default_template_name =&amp;gt; "contact_form" 
default_template_format =&amp;gt; :html&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this method, we are checking to see if there is a template with the above params.  Since we dont have any layouts Rails throws an &lt;code&gt;ActionView::MissingTemplate&lt;/code&gt; exception which we catch and just return true from it.  This sets up the final part of &lt;code&gt;pick_layout&lt;/code&gt; which is &lt;code&gt;active_layout&lt;/code&gt;.  Here is the definition for that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# (line 201 action_pack/action_controller/layout.rb)
def active_layout(passed_layout = nil, options = {})
  layout = passed_layout || default_layout
  return layout if layout.respond_to?(:render)

  active_layout = case layout
    when Symbol then __send__(layout)
    when Proc   then layout.call(self)
    else layout
  end

  find_layout(active_layout, default_template_format, options[:html_fallback]) if active_layout
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In our case, we dont pass anything to active_layout so the first line will get set to &lt;code&gt;default_layout&lt;/code&gt;, which is a private method that looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# (line 220 action_pack/action_controller/layout.rb)
def default_layout #:nodoc:
  layout = self.class.read_inheritable_attribute(:layout)
  return layout unless self.class.read_inheritable_attribute(:auto_layout)
  find_layout(layout, default_template_format)
rescue ActionView::MissingTemplate
  nil
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since we didnt set a layout, the first line will return &lt;code&gt;nil&lt;/code&gt; and the second line will return that value because &lt;code&gt;auto_layout&lt;/code&gt; will also be nil.  When we get back to &lt;code&gt;active_layout&lt;/code&gt;, the variable &lt;code&gt;layout&lt;/code&gt; is set to &lt;code&gt;nil&lt;/code&gt;. The variable &lt;code&gt;active_layout&lt;/code&gt; gets set to &lt;code&gt;nil&lt;/code&gt; as well since we are layout-less.  Now we get to &lt;code&gt;find_layout&lt;/code&gt; which doesnt get called in our example because &lt;code&gt;active_layout&lt;/code&gt; is &lt;code&gt;nil&lt;/code&gt;.  That&#8217;s it, we are now ready to do the main rendering.  Let&#8217;s look at the code again:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(line 562 action_mailer/base.rb)
def render(opts)
  ...
  begin
    old_template, @template = @template, initialize_template_class(body)
    layout = respond_to?(:pick_layout, true) ? pick_layout(opts) : false
    @template.render(opts.merge(:layout =&amp;gt; layout))
  ensure
    @template = old_template
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and the params and current variables with our example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;opts =&amp;gt; {
  :file =&amp;gt; "contact_form",
  :body =&amp;gt; {:message=&amp;gt;"Send this message"}
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;old_template  =&amp;gt; "contact_form" 
@template =&amp;gt; #&amp;lt;ActionView::Base:0x3496c10 
                @template_format=:html, 
                @assigns={:message=&amp;gt;"Send this message"}, 
                @helpers=#&amp;lt;ActionView::Base::ProxyModule:0x3496b84&amp;gt;, 
                @controller=#&amp;lt;MessageMailer:0x34a5814 
                @action_name="contact_form", 
                @subject="Im contacting you", 
                @content_type="text/plain", 
                @implicit_parts_order=["text/html", "text/enriched", "text/plain"], 
                @from="jake@somewhere.com", 
                @sent_on=Sun Nov 08 18:15:42 -0600 2009, 
                @headers={}, 
                @default_template_name="contact_form", 
                @mime_version="1.0", 
                @body={:message=&amp;gt;"Send this message"}, 
                @mailer_name="message_mailer", 
                @recipients="someemail@somedomain.com", 
                @parts=[], 
                @template=#&amp;lt;ActionView::Base:0x3496c10 ...&amp;gt;, 
                @charset="utf-8"&amp;gt;, 
                @_current_render=nil, 
                @assigns_added=nil, 
                @_first_render=nil,
                @view_paths=["/example_app/app/views"]&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So now we see that &lt;code&gt;layout&lt;/code&gt; ends up being nil in our example which we then pass on to &lt;code&gt;@template.render&lt;/code&gt; along with our original options.  Now we&#8217;ll jump into &lt;code&gt;render&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# (line 201 action_view/base.rb)
def render(options = {}, local_assigns = {}, &amp;#38;block) #:nodoc:
  local_assigns ||= {}

  case options
  when Hash
    options = options.reverse_merge(:locals =&amp;gt; {})
    if options[:layout]
      _render_with_layout(options, local_assigns, &amp;#38;block)
    elsif options[:file]
      template = self.view_paths.find_template(options[:file], template_format)
      template.render_template(self, options[:locals])
    elsif options[:partial]
      render_partial(options)
    elsif options[:inline]
      InlineTemplate.new(options[:inline], options[:type]).render(self, options[:locals])
    elsif options[:text]
      options[:text]
    end
  when :update
    update_page(&amp;#38;block)
  else
    render_partial(:partial =&amp;gt; options, :locals =&amp;gt; local_assigns)
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and our passed in params:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;options =&amp;gt; {:file=&amp;gt;"message_mailer/contact_form", :layout=&amp;gt;nil}
local_assigns =&amp;gt; {}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since &lt;code&gt;options&lt;/code&gt; is a Hash, we jump right in and first merge in &lt;code&gt;:locals =&amp;gt; {}&lt;/code&gt; with &lt;code&gt;options&lt;/code&gt;.  &lt;code&gt;options[:layout]&lt;/code&gt; returns nil so we skip that statement and go into the &lt;code&gt;options[:file]&lt;/code&gt; conditional&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;template = self.view_paths.find_template(options[:file], template_format)
template.render_template(self, options[:locals])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, we search out the template from the AM models &lt;code&gt;view_paths&lt;/code&gt; with our file and the &lt;code&gt;temlpate_format&lt;/code&gt;, which in our case is &lt;code&gt;:html&lt;/code&gt;.  &lt;code&gt;view_paths&lt;/code&gt; is an instance method in &lt;code&gt;ActionView::Base&lt;/code&gt; that accesses the attribute &lt;code&gt;@view_paths&lt;/code&gt; which holds an instance of &lt;code&gt; ActionView::PathSet&lt;/code&gt;. This is a helper class that wraps an array with some pretty handy methods, one of which is &lt;code&gt;find_template&lt;/code&gt;. This helper class stores each of the view_paths as a &lt;code&gt;ActionView::ReloadableTemplate::ReloadablePath&lt;/code&gt; object.  This allows us to do other cooler things which we go over later.  In our case, &lt;code&gt;view_paths&lt;/code&gt; returns:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;self.view_paths =&amp;gt; ["/example_app/app/views"]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&#8217;s dive into &lt;code&gt;find_template&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# (line 201 action_pack/action_view/paths.rb)
def find_template(original_template_path, format = nil, html_fallback = true)
  return original_template_path if original_template_path.respond_to?(:render)
  template_path = original_template_path.sub(/^\//, '')

  each do |load_path|
    if format &amp;#38;&amp;#38; (template = load_path["#{template_path}.#{I18n.locale}.#{format}"])
      return template
    elsif format &amp;#38;&amp;#38; (template = load_path["#{template_path}.#{format}"])
      return template
    elsif template = load_path["#{template_path}.#{I18n.locale}"]
      return template
    elsif template = load_path[template_path]
      return template
    # Try to find html version if the format is javascript
    elsif format == :js &amp;#38;&amp;#38; html_fallback &amp;#38;&amp;#38; template = load_path["#{template_path}.#{I18n.locale}.html"]
      return template
    elsif format == :js &amp;#38;&amp;#38; html_fallback &amp;#38;&amp;#38; template = load_path["#{template_path}.html"]
      return template
    end
  end

  return Template.new(original_template_path, original_template_path =~ /\A\// ? "" : ".") if File.file?(original_template_path)

  raise MissingTemplate.new(self, original_template_path, format)
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and our params:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;original_template_path =&amp;gt; "message_mailer/contact_form" 
format =&amp;gt; :html&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first line just returns back if we have a full fledged ActionView model that responds to render.  Since we dont, we keep going and see that the next line makes sure that our &lt;code&gt;original_template_path&lt;/code&gt; isnt an absolute path by removing the initial &#8220;/&#8221; if it is there and storing the final result in &lt;code&gt;template_path&lt;/code&gt;.  Next, we iterate over ourselves and do some checking (remember, PathSet is a subclass of Array, so we can call &lt;code&gt;each&lt;/code&gt; and iterate over the contents internally).  In our example, we end up executing the line:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;elsif template = load_path[template_path]
  return template&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is part of the fanciness of &lt;code&gt;ActionView::ReloadableTemplate::ReloadablePath&lt;/code&gt;.  One of the methods implemented is &lt;code&gt;[]&lt;/code&gt; which works like a hash and pulls out the proper &lt;code&gt;ReloadableTemplate&lt;/code&gt; from the paths array, in our case it&#8217;s&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;template =&amp;gt; #&amp;lt;ActionView::ReloadableTemplate:0x34a2ad8 
              @base_path="message_mailer", 
              @template_path="message_mailer/contact_form.erb", 
              @_memoized_path=["message_mailer/contact_form.erb"], 
              @name="contact_form", 
              @previously_last_modified=Sat Nov 07 10:32:50 -0600 2009, 
              @_memoized_method_segment=["app47views47message_mailer47contact_form46erb"], 
              @format=nil, 
              @filename="/example_app/app/views/message_mailer/contact_form.erb", 
              @_memoized_relative_path=["app/views/message_mailer/contact_form.erb"], 
              @extension="erb", 
              @locale=nil, 
              @_memoized_path_without_extension=["message_mailer/contact_form"], 
              @_memoized_method_name_without_locals=["_run_erb_app47views47message_mailer47contact_form46erb"], 
              @load_path="/example_app/app/views"&amp;gt;

So we found the proper view and we are now done with @find_template@. Back to @render@:&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# (line 201 action_pack/action_view/base.rb)
def render(options = {}, local_assigns = {}, &amp;#38;block) #:nodoc:
  local_assigns ||= {}

  case options
  when Hash
    ...
    elsif options[:file]
      template = self.view_paths.find_template(options[:file], template_format)
      template.render_template(self, options[:locals])
    elsif options[:partial]
      ...
    end
  when :update
    ...
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The next line renders the template with any locals (in our case there are none). Before we dive into &lt;code&gt;render_template&lt;/code&gt; &#8216;s definition, let&#8217;s take a look at the view we created for our example message:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
(message_mailer/contact_form.erb)

Hi,

I am contacting you with this message:

&amp;lt;%= @message %&amp;gt;

Thanks

Jake
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A ridiculously simple mailer view for our equally ridiculously simple mailer message.  Back to &lt;code&gt;render_template&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# (line 193 action_pack/action_view/template.rb)
def render_template(view, local_assigns = {})
  render(view, local_assigns)
rescue Exception =&amp;gt; e
  raise e unless filename
  if TemplateError === e
    e.sub_template_of(self)
    raise e
  else
    raise TemplateError.new(self, view.assigns, e)
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and our current params:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;view  =&amp;gt; #&amp;lt;ActionView::Base:0x3496c10 
              @template_format=:html, 
              @assigns={:message=&amp;gt;"Send this message"}, 
              @helpers=#&amp;lt;ActionView::Base::ProxyModule:0x3496b84&amp;gt;, 
              @controller=#&amp;lt;MessageMailer:0x34a5814 
              @action_name="contact_form", 
              @subject="Im contacting you", 
              @content_type="text/plain", 
              @implicit_parts_order=["text/html", "text/enriched", "text/plain"], 
              @from="jake@somewhere.com", 
              @sent_on=Mon Nov 09 20:09:58 -0600 2009, 
              @headers={}, 
              @default_template_name="contact_form", 
              @mime_version="1.0", 
              @body={:message=&amp;gt;"Send this message"}, 
              @mailer_name="message_mailer", 
              @recipients="someemail@somedomain.com", 
              @parts=[], 
              @template=#&amp;lt;ActionView::Base:0x3496c10 ...&amp;gt;, 
              @charset="utf-8"&amp;gt;, 
              @_current_render=nil, 
              @assigns_added=nil, 
              @_first_render=nil, 
              @view_paths=["/example_app/app/views"]&amp;gt;
local_assigns =&amp;gt; {}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As we can see, &lt;code&gt;render_template&lt;/code&gt; is a relatively simple method that delegates most of it&#8217;s work to &lt;code&gt;Renderable#render&lt;/code&gt;.  That&#8217;s where we are going next:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# (line 193 action_pack/action_view/renderable.rb)
def render(view, local_assigns = {})
  compile(local_assigns)

  view.with_template self do
    view.send(:_evaluate_assigns_and_ivars)
    view.send(:_set_controller_content_type, mime_type) if respond_to?(:mime_type)

    view.send(method_name(local_assigns), local_assigns) do |*names|
      ivar = :@_proc_for_layout
      if !view.instance_variable_defined?(:"@content_for_#{names.first}") &amp;#38;&amp;#38; view.instance_variable_defined?(ivar) &amp;#38;&amp;#38; (proc = view.instance_variable_get(ivar))
        view.capture(*names, &amp;#38;proc)
      elsif view.instance_variable_defined?(ivar = :"@content_for_#{names.first || :layout}")
        view.instance_variable_get(ivar)
      end
    end
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Whew, that&#8217;s it for this week.  Next week, we get super deep into rendering and see how Rails performs all of it&#8217;s rendering duties.&lt;/p&gt;</description>
      <pubDate>Sun, 22 Nov 2009 10:34:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:f885df96-11f6-4eb4-8052-490abe39604b</guid>
      <author>jake</author>
      <link>http://blog.flvorful.com/articles/2009/11/22/deep-in-rails-actionmailer-deliver-part-ii</link>
      <category>Rails</category>
      <category>rails</category>
      <category>action_mailer</category>
      <category>deep</category>
      <category>DIR</category>
      <category>part2</category>
    </item>
    <item>
      <title>Deep in Rails: ActionMailer#deliver Part I</title>
      <description>
&lt;p&gt;Welcome to the first in a series of articles that will delve deep into several commonly used methods of Rails. The first method we will look at is Actionmailer#deliver.  Now, I am going to assume that you know what AM is and how to use.  You&amp;#8217;ve generated mailer models before and set up views and called these methods via something like: &lt;code&gt;MyMailer.deliver_some_message(insert, your, params, here)&lt;/code&gt;.  What we are going to to look at is what happens when you make the deliver call.&lt;/p&gt;
&lt;p&gt;We will be skipping what happens around rails (the ruby core goings-ons) and all the method stacking that goes on in ruby and focus on the rails part in this series.  So let&amp;#8217;s get started. (We will be using &lt;a href="http://rubyforge.org/frs/download.php/53272/rails-2.3.2.tgz"&gt;Rails 2.3.2&lt;/a&gt; as the guide for the code)&lt;/p&gt;
&lt;h2&gt;What&amp;#8217;s happening now?&lt;/h2&gt;
&lt;p&gt;When &lt;code&gt;deliver_some_message&lt;/code&gt; is executed, the first method that is fired is AR&amp;#8217;s class method &lt;code&gt;method_missing&lt;/code&gt;.  Here&amp;#8217;s the method that gets executed:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(line 391 action_mailer/base.rb)
class &amp;lt;&amp;lt; self
  ...
  def method_missing(method_symbol, *parameters) #:nodoc:
    if match = matches_dynamic_method?(method_symbol)
      case match[1]
        when 'create'  then new(match[2], *parameters).mail
        when 'deliver' then new(match[2], *parameters).deliver!
        when 'new'     then nil
      else super
      end
    else
      super
    end
  end
  ...
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So when you call &lt;code&gt;deliver_some_message(params)&lt;/code&gt;, ruby passes all that info (method name included) to the method_missing method.  I have created a simple Mailer for this series to help us see what&amp;#8217;s going on throughout this entire chain of methods and to see each of the params for these methods.&lt;/p&gt;
&lt;p&gt;Here is the quick mailer I created:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class MessageMailer &amp;lt; ActionMailer::Base
  def contact_form(msg_from, message)
    subject    'Im contacting you'
    recipients "someemail@somedomain.com"
    from       msg_from
    sent_on    Time.now
    body       :message =&amp;gt; message
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So when I call&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MessageMailer.deliver_contact_form("jake@somewhere.com", "Send this message")&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;the params end up being distributed like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;method_symbol =&amp;gt; :deliver_contact_form
parameters =&amp;gt; ["jake@somewhere.com", "Send this message"]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we know what&amp;#8217;s being passed, let&amp;#8217;s see what happens to it.  The first line of the method is&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if match = matches_dynamic_method?(method_symbol)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;matches_dynamic_method?&lt;/code&gt; is a private method in AM and is defined as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(line 441 action_mailer/base.rb)
private
  def matches_dynamic_method?(method_name) #:nodoc:
    method_name = method_name.to_s
    /^(create|deliver)_([_a-z]\w*)/.match(method_name) || /^(new)$/.match(method_name)
  end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is pretty simple, we are doing a scan across the method name to match it against &lt;strong&gt;create_&lt;/strong&gt; or &lt;strong&gt;deliver_&lt;/strong&gt; and then capturing the rest of the method name  or we are looking strictly for &lt;strong&gt;new&lt;/strong&gt; at the beginning of our method name and with nothing else attached. The reason this is done is to disable AM&amp;#8217;s initialize capabilities for outside referencing and only offer &lt;code&gt;create&lt;/code&gt; and &lt;code&gt;deliver&lt;/code&gt;.   On line 254 in AR base.rb we see that we have privatize the method new with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private_class_method :new #:nodoc:&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So if someone tries to be clever and call &lt;code&gt;MessageMailer.new&lt;/code&gt;, it will hit the &lt;code&gt;method_missing&lt;/code&gt; (since the base new method has now been made private) and end up returning nil.&lt;/p&gt;
&lt;p&gt;The match method returns a &lt;code&gt;Match&lt;/code&gt; object that contains the captures. With our example the match variable would look like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;match.captures =&amp;gt; ["deliver", "contact_form"]
match[1] =&amp;gt; deliver
match[2] =&amp;gt; contact_form&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So now we got a match and we can continue thru the case statement.  Since &lt;code&gt;match[1]&lt;/code&gt; in our example returns &lt;code&gt;deliver&lt;/code&gt;, we execute the line&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;when 'deliver' then new(match[2], *parameters).deliver!&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, we call the private &lt;code&gt;new&lt;/code&gt; method to initialize a new AR instance and we pass it the second part of our capture and all the params that came to method_missing originally.  After initializing, the method &lt;code&gt;deliver!&lt;/code&gt; is then called (which we will talk about after we talk about what happens during initialization).&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s go ahead and see what &lt;code&gt;new&lt;/code&gt; looks like (or more precisely, &lt;code&gt;initialize&lt;/code&gt;, since you dont create a &lt;code&gt;new&lt;/code&gt; method, you create the &lt;code&gt;initialize&lt;/code&gt; method which new calls).  AR&amp;#8217;s &lt;code&gt;initialize&lt;/code&gt; method looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(line 452 action_mailer/base.rb)
def initialize(method_name=nil, *parameters) #:nodoc:
  create!(method_name, *parameters) if method_name
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This &lt;code&gt;initialize&lt;/code&gt; is quite simple, it calls &lt;code&gt;create!&lt;/code&gt; if &lt;code&gt;method_name&lt;/code&gt; is present.  In our case it will be since we passed &amp;#8220;contact_form&amp;#8221; to it.  So let&amp;#8217;s go to &lt;code&gt;create!&lt;/code&gt; which is also right below it in the source:&lt;/p&gt;
&lt;pre&gt;
  &lt;code&gt; 
(line 458 action_mailer/base.rb)
def create!(method_name, *parameters) #:nodoc:
  initialize_defaults(method_name)
  __send__(method_name, *parameters)

  unless String === @body
    if @parts.empty?
      Dir.glob("#{template_path}/#{@template}.*").each do |path|
        template = template_root["#{mailer_name}/#{File.basename(path)}"]
        
        next unless template &amp;amp;&amp;amp; template.multipart?
        
        @parts &amp;lt;&amp;lt; Part.new(
          :content_type =&amp;gt; template.content_type,
          :disposition =&amp;gt; "inline",
          :charset =&amp;gt; charset,
          :body =&amp;gt; render_message(template, @body)
        )
      end
      unless @parts.empty?
        @content_type = "multipart/alternative" if @content_type !~ /^multipart/
        @parts = sort_parts(@parts, @implicit_parts_order)
      end
    end
    
    template_exists = @parts.empty?
    template_exists ||= template_root["#{mailer_name}/#{@template}"]
    @body = render_message(@template, @body) if template_exists
    
    if !@parts.empty? &amp;amp;&amp;amp; String === @body
      @parts.unshift Part.new(:charset =&amp;gt; charset, :body =&amp;gt; @body)
      @body = nil
    end
  end
  
  @mime_version ||= "1.0" if !@parts.empty?
  
  @mail = create_mail
end
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Whoa!  Don&amp;#8217;t worry, it&amp;#8217;s not that bad.  Let&amp;#8217;s take it line by line. Note: I have removed the comments from the above snippet because they wouldnt format in textile properly.&lt;/p&gt;
&lt;p&gt;First, let&amp;#8217;s figure out what we have in the method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;method_name =&amp;gt; "contact_form"
parameters =&amp;gt; ["jake@somewhere.com", "Send this message"]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cool, now we know what we have going in, so let&amp;#8217;s step through it.  First we have: &lt;code&gt;initialize_defaults(method_name)&lt;/code&gt; which is a private method in AM&lt;/p&gt;
&lt;p&gt;which looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(line 537 action_mailer/base.rb)
def initialize_defaults(method_name)
  @charset ||= @@default_charset.dup
  @content_type ||= @@default_content_type.dup
  @implicit_parts_order ||= @@default_implicit_parts_order.dup
  @template ||= method_name
  @default_template_name = @action_name = @template
  @mailer_name ||= self.class.name.underscore
  @parts ||= []
  @headers ||= {}
  @body ||= {}
  @mime_version = @@default_mime_version.dup if @@default_mime_version
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This method initializes several of the attribute accessors, or in this case advanced attribute accessors, with defaults and some class attribute accessors.  The advanced attribute accessors are just like regular attribute accessors except they add one extra ability which you have seen several times in your use of ActionMailer models.  Take a look at our simple mailer again:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class MessageMailer &amp;lt; ActionMailer::Base
  def contact_form(msg_from, message)
    subject    'Im contacting you'
    ...
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Do you see it?  Notice, how we can make the call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;subject    'Im contacting you'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is not a normal attribute accessor call.  Normally, you can only call&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;obj.some_attribute&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;obj.some_attribute =  "some stuff"&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The advanced attribute accessor gives you a third option of setting the attribute via a regular method call like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;obj.some_attribute("some stuff")&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or, more elegantly:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;obj.some_attribute "some stuff"&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;instead of the regular ol&amp;#8217;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;obj.some_attribute = "some stuff"&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;#8217;s see how AM accomplishes this.  Take a look at &lt;code&gt;action_mailer/adv_attr_accessor.rb&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;
  &lt;code&gt;
module ActionMailer
  module AdvAttrAccessor #:nodoc:
    def self.included(base)
      base.extend(ClassMethods)
    end

    module ClassMethods #:nodoc:
      def adv_attr_accessor(*names)
        names.each do |name|
          ivar = "@#{name}"

          define_method("#{name}=") do |value|
            instance_variable_set(ivar, value)
          end

          define_method(name) do |*parameters|
            raise ArgumentError, "expected 0 or 1 parameters" unless parameters.length &amp;lt;= 1
            if parameters.empty?
              if instance_variable_names.include?(ivar)
                instance_variable_get(ivar)
              end
            else
              instance_variable_set(ivar, parameters.first)
            end
          end
        end
      end
    end
  end
end
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;The main part of all of that is the &lt;code&gt;adv_attr_accessor(*names)&lt;/code&gt; definition.  What Rails is doing here is going over each name (or attribute) you want to create and then doing the following:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Dynamically creating an instance variable name.&lt;/li&gt;
	&lt;li&gt;Dynamically creating a &lt;code&gt;method=&lt;/code&gt; method (or setter method) for the attribute.&lt;/li&gt;
	&lt;li&gt;Dynamically creating a &lt;code&gt;method&lt;/code&gt; method (or getter method) for the attribute, but (and this is where the magic is) adding the ability to have 0 or 1 parameters (instead of the normal 0 parameters that Ruby normally provides).  If the parameters to the method is 0 then it just gets the instance variable (attribute) as normal, if it is 1, then it sets the instance variable to the parameter (like the normal &lt;code&gt;method=&lt;/code&gt; method does).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&amp;#8217;s how we get the sugar coated ability to write &lt;code&gt;obj.some_attribute "some stuff"&lt;/code&gt; for our AM methods.&lt;/p&gt;
&lt;p&gt;Ok, now back to &lt;code&gt;initialize_defaults&lt;/code&gt;.  So we see the attributes getting initialized, let&amp;#8217;s see how our example would initialize:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;method_name           =&amp;gt; contact_form
charset               =&amp;gt; "utf-8"
content_type          =&amp;gt; "text/plain"
implicit_parts_order  =&amp;gt; ["text/html", "text/enriched", "text/plain"]
template.inspect      =&amp;gt; "contact_form"
default_template_name =&amp;gt; "contact_form"
action_name           =&amp;gt; contact_form
mailer_name           =&amp;gt; "message_mailer"
parts                 =&amp;gt; []
headers               =&amp;gt; {}
body                  =&amp;gt; {}
mime_version          =&amp;gt; "1.0"&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cool, now that we got that all initialized, let&amp;#8217;s keep going.  Back to create!:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(line 458 action_mailer/base.rb)
def create!(method_name, *parameters) #:nodoc:
  initialize_defaults(method_name)
  __send__(method_name, *parameters)
  ...
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The next line calls &lt;code&gt;__send__&lt;/code&gt; with the method_name and parameters that we passed in originally.  The reason &lt;code&gt;__send__&lt;/code&gt; is called is just in case you override the normal send method.  This is a nice lesson for you newcomers to Rails.  &lt;span class="caps"&gt;DONT&lt;/span&gt; &lt;span class="caps"&gt;OVERRIDE&lt;/span&gt; &lt;span class="caps"&gt;CORE&lt;/span&gt; &lt;span class="caps"&gt;RUBY&lt;/span&gt; &lt;span class="caps"&gt;METHODS&lt;/span&gt;!  Sorry for the yelling.&lt;/p&gt;
&lt;p&gt;But, since we cant predict everything, more specifically, we cant predict what new rails developers will do with AM, we use the &lt;code&gt;__send__&lt;/code&gt; method the make sure we dynamically call &lt;code&gt;method_name&lt;/code&gt; with the parameters and not an overridden send method in your customized AM class.&lt;/p&gt;
&lt;p&gt;In our example, we have the following arguments to send:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;method_name =&amp;gt; "contact_form"
parameters =&amp;gt; ["jake@somewhere.com", "Send this message"]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So Ruby sends the message &amp;#8220;contact_form&amp;#8221; to our instantiated AM model and since we defined &lt;code&gt;contact_form&lt;/code&gt; in our mailer model Ruby will execute this method now.  Let&amp;#8217;s look at our mailer again:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class MessageMailer &amp;lt; ActionMailer::Base
  def contact_form(msg_from, message)
    subject    'Im contacting you'
    recipients "someemail@somedomain.com"
    from       msg_from
    sent_on    Time.now
    body       :message =&amp;gt; message
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we have seen how the &lt;code&gt;adv_attr_accessors&lt;/code&gt; work we can see that all that our &lt;code&gt;contact_form&lt;/code&gt; method (or any AM deliver method for that matter) is doing is setting all the proper attributes.  Your view is just an &lt;span class="caps"&gt;HTML&lt;/span&gt; or plain text version of your email with some fancy &lt;span class="caps"&gt;ERB&lt;/span&gt; parsing to help make it dynamic.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s keep going.  We have just set several attributes using the dynamic &lt;code&gt;__send__&lt;/code&gt; method to call our contact_form method in our AM model.  Now we are back to the &lt;code&gt;create!&lt;/code&gt; method again:&lt;/p&gt;
&lt;pre&gt;
  &lt;code&gt; 
(line 458 action_mailer/base.rb)
def create!(method_name, *parameters) #:nodoc:
  initialize_defaults(method_name)
  __send__(method_name, *parameters)

  unless String === @body
    if @parts.empty?
      Dir.glob("#{template_path}/#{@template}.*").each do |path|
        template = template_root["#{mailer_name}/#{File.basename(path)}"]
        
        next unless template &amp;amp;&amp;amp; template.multipart?
        
        @parts &amp;lt;&amp;lt; Part.new(
          :content_type =&amp;gt; template.content_type,
          :disposition =&amp;gt; "inline",
          :charset =&amp;gt; charset,
          :body =&amp;gt; render_message(template, @body)
        )
      end
      unless @parts.empty?
        @content_type = "multipart/alternative" if @content_type !~ /^multipart/
        @parts = sort_parts(@parts, @implicit_parts_order)
      end
    end
    ...
  end
  ...
end
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;The next thing we do is check to see whether our &lt;code&gt;body&lt;/code&gt; attribute is a String.  If not, we are going to do some processing.  Let&amp;#8217;s take a look and see what attributes we have set with our example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@parts           =&amp;gt; nil
@template        =&amp;gt; "contact_form"&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we know that (in our example) parts is empty and we are going to enter into that conditional statement.  Now we are going to find all template views that match our template &amp;#8220;contact_form&amp;#8221;.  &lt;code&gt;template_root&lt;/code&gt; is a class method on AM that returns the view_path root (usually apps/views/).  This method is copied from &lt;code&gt;ActionView::Base&lt;/code&gt; and the root is set there.&lt;/p&gt;
&lt;p&gt;Next, we will set the variable &lt;code&gt;template&lt;/code&gt; to be the value of &lt;code&gt;template_root&lt;/code&gt; when the key is the full path (with the &lt;code&gt;mailer_name&lt;/code&gt;, in this case &amp;#8220;message_mailer&amp;#8221;) to the erb or rhtml file.  What we get back, is an instance of &lt;code&gt;ActionView::ReloadableTemplate&lt;/code&gt; wrapped around our view file.  Let&amp;#8217;s see that with our example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;template  =&amp;gt; 
  #&amp;lt;ActionView::ReloadableTemplate:0x34a4a68 
    @base_path="message_mailer", 
    @template_path="message_mailer/contact_form.erb", 
    @_memoized_path=["message_mailer/contact_form.erb"], 
    @name="contact_form", 
    @filename="/example_app/app/views/message_mailer/contact_form.erb", 
    ...
    @load_path="/example_app/app/views"&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we see that we skip over any further processing unless we have a multipart message or have multiple views for our mailer method (thereby making it a multipart message).  That takes us out of the loop (for our example) and down to&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;unless @parts.empty?
  @content_type = "multipart/alternative" if @content_type !~ /^multipart/
  @parts = sort_parts(@parts, @implicit_parts_order)
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In our example, &lt;code&gt;@parts&lt;/code&gt; is empty so we are pretty much done with this area.  Let&amp;#8217;s take a look and see what happens next:&lt;br /&gt;
&lt;pre&gt;&lt;br /&gt;
  &lt;code&gt;
def create!(method_name, *parameters) #:nodoc:
  ...
  unless String === @body
    if @parts.empty?
      ...
    end
    
    template_exists = @parts.empty?
    template_exists ||= template_root["#{mailer_name}/#{@template}"]
    @body = render_message(@template, @body) if template_exists
    ...
  end
end
&lt;/code&gt;&lt;br /&gt;
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Basically, what we are doing here is making sure we have either an implied template or dynamically generated template.  This is mainly for multipart messages.  In our example, since there are still no parts, template_exist gets set to true.  Since it is already true, the next line gets skipped and we go directly to rendering the message into our protected attribute &lt;code&gt;@body&lt;/code&gt;.  Let&amp;#8217;s see what render_message looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(line 553 action_mailer/base.rb)
def render_message(method_name, body)
  if method_name.respond_to?(:content_type)
    @current_template_content_type = method_name.content_type
  end
  render :file =&amp;gt; method_name, :body =&amp;gt; body
ensure
  @current_template_content_type = nil
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When we call &lt;code&gt;render_message&lt;/code&gt; in &lt;code&gt;create!&lt;/code&gt;, we call it with &lt;code&gt;@template&lt;/code&gt; and &lt;code&gt;@body&lt;/code&gt;, let&amp;#8217;s see what those get set to inside of &lt;code&gt;render_message&lt;/code&gt; for our example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@template   = method_name     =&amp;gt; "contact_form"
@body       = body            =&amp;gt; {:message=&amp;gt;"Send this message"}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At the beginning of render_message &lt;code&gt;@body&lt;/code&gt; is set to the hash of instance variables that we set in our &lt;code&gt;contact_form&lt;/code&gt; method in our mailer.  Once we are finished processing, that hash will be gone and &lt;code&gt;@body&lt;/code&gt; will be replaced with the full rendered message.&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s it for now.  Stay tuned for next week for Part II where we will pick back up and continue our trek through ActionMailer#deliver and get real deep into rendering.&lt;/p&gt;

</description>
      <pubDate>Sun, 15 Nov 2009 14:59:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:52c964ef-9dfb-4d83-a908-b58fc5774ea6</guid>
      <author>jake</author>
      <link>http://blog.flvorful.com/articles/2009/11/15/deep-in-rails-actionmailer-deliver-part-i</link>
      <category>Rails</category>
      <category>rails</category>
      <category>action_mailer</category>
      <category>deep</category>
      <category>DIR</category>
      <category>part1</category>
      <trackback:ping>http://blog.flvorful.com/articles/trackback/12</trackback:ping>
    </item>
  </channel>
</rss>

