<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog - ShiftEleven &#187; respond_to</title>
	<atom:link href="http://shifteleven.com/articles/tag/respond_to/feed" rel="self" type="application/rss+xml" />
	<link>http://shifteleven.com</link>
	<description></description>
	<lastBuildDate>Mon, 09 Jan 2012 04:04:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>DRYing Up respond_to</title>
		<link>http://shifteleven.com/articles/2006/11/26/drying-up-respond_to?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=drying-up-respond_to</link>
		<comments>http://shifteleven.com/articles/2006/11/26/drying-up-respond_to#comments</comments>
		<pubDate>Sun, 26 Nov 2006 23:34:58 +0000</pubDate>
		<dc:creator>K. Adam Christensen</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[metaprogramming]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[respond_to]]></category>

		<guid isPermaLink="false">http://dev.fecalrod.com/?p=19</guid>
		<description><![CDATA[Now that that release candidate for rails 1.2 is out, people are going to have even more reasons to use the respond_to method in their controller methods. With that, there may come some unsettling feeling that you&#8217;re just repeating yourself &#8230; <a href="http://shifteleven.com/articles/2006/11/26/drying-up-respond_to">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Now that that <a href="http://blog.rubyonrails.org/2006/11/23/rails-1-2-release-candidate-1">release candidate for rails 1.2</a> is out, people are going to have even more reasons to use the <code>respond_to</code> method in their controller methods.  With that, there may come some unsettling feeling that you&#8217;re just repeating yourself over and over again.</p>
<pre class="ruby" title="code">def index
  @articles = Article.find(:all)
  respond_to do |format|
    format.html
    format.xml { render :xml =&gt; @articles.to_xml }
  end
end

def show
  @article = Article.find(params[:id])
  respond_to do |format|
    format.html
    format.xml { render :xml =&gt; @article.to_xml }
  end
end</pre>
<p>If we want to use the <code>respond_to</code>, we have to make sure it&#8217;s in all of our methods.  Wouldn&#8217;t it be easier to just do something like this?</p>
<pre class="ruby" title="code">def index
  @articles = Article.find(:all)
  format.html
  format.xml { render :xml =&gt; @articles.to_xml }
end</pre>
<p>Doing it this way, we don&#8217;t have to write 2 extra lines per method, and we don&#8217;t increase our indentation.  While that&#8217;s not a huge thing, I still just don&#8217;t like to constantly write out those lines when I don&#8217;t have to when I think we can build something a little trickier.  <span id="more-19"></span></p>
<h3>The Breakdown</h3>
<p>In the simplified example I gave above, we have several things that we need to accomplish.  One is to wrap our methods with a <code>respond_to</code> by using <a href="http://www.rubycentral.com/book/classes.html."><code>alias_method</code></a> Well, it&#8217;s actually not that simple because <code>respond_to</code> is a block and we will need to do some trickery there.  Another task is we need to create a <code>format</code> method.  Since we won&#8217;t be calling <code>format</code> with a block parameter, we need to make a method which will do the dirty work for us.  Finally, we need to make a tweak to <code>ActionController::MimeResponders::Respond#respond</code> for some of the other things that we are doing.</p>
<h4>Adding <code>wrap_respond_to_in</code> to our ApplicationController</h4>
<p>To start things off, we need to make a class method, which I have dubbed <code>wrap_respond_to_in</code> (I would <strong>love</strong> suggestions for names here).</p>
<pre class="ruby" title="code">class &lt;&lt; self
  def wrap_respond_to_in(*actions)
    if actions.include?(:all)
      # Also remove #rescue_action because this gets set in tests. Also include some of my friendly #find methods.
      actions = actions + self.public_instance_methods - ApplicationController.public_instance_methods - ['rescue_action'] - [:all]
      [:find_collection, :find_new, :find_member].each do |finder|
        actions &lt;&lt; finder if method_defined?(finder)
      end
    end

    # Returns the appropriate Responder format based on the action.
    define_method(:format) do
      @format.last rescue nil
    end

    for action in actions
      action = action.to_sym

      module_eval &lt;&lt;-END
        alias_method(:__#{action.to_i}__, :#{action.to_s})
        private :__#{action.to_i}__

        def #{action.to_s}(*args)
          result = nil      # This is the result of whatever method this wraps
          respond_to do |format|
            @format ||= []
            @format.push(format)
            result = __#{action.to_i}__(*args)
            @format.pop
          end
          return result
        end
      END
    end
  end
end</pre>
<p>Let&#8217;s break this down by section.  First things first, the method&#8217;s arguments should be a list of symbols for the names of the methods we would like to use our <code>respond_to</code> shorthand.  Because I would like to use this shorthand for all of my action methods, I have included the notion of sending <code>:all</code> as a parameter.  This will make sure that all of the public methods and some protected methods that I use (<code>find_member</code>, <code>find_collection</code>, and <code>find_new</code>).  Again, I like to keep things DRY(Don&#8217;t Repeat Yourself).  Next we define a method called <code>format</code>.  This will be an accessor to the last element of our <code>format</code> instance variable array.  More on this later.  After we have defined that, we need to loop through all of our methods that we want to use <code>respond_to</code>.  In each loop, we need to make an alias for our methods.  This is so that we can re-write the method, yet still keep a copy of the original code.  Next we overwrite the method.  As you can see here, this is where we put the <code>respond_to</code> block.  Now in this block, we have access to the <code>format</code> variable.  Next we push this value into our <code>format</code> instance variable.  The reasoning for using an array is to accommodate for a nested set of calls.  After we push <code>format</code> onto <code>format</code>, we then call our original method, which uses the shorthand and save that to to a variable.  Once that is done, we pop off the last value we put into the format@ variable, since we are done with it.  Finally, return the result of our original method.  This is the backbone for what we need to do.  Now we need to implement it.</p>
<h4>Tweaking ActionController::MimeResponds::Responder</h4>
<p>Because we now have assumed that all of our methods are going to use <code>respond_to</code>, we need to make a way out if for some reason we don&#8217;t need to use said method.  This would mean that our method exists without calling the <code>format</code> method.  In order to do that, we can use the following code:</p>
<pre class="ruby" title="code">module ActionController #:nodoc:
  module MimeResponds #:nodoc:
    class Responder
      alias_method :__respond_without_check_for_empty_order__, :respond
      private :__respond_without_check_for_empty_order__

      def respond
        return if @order.empty?
        __respond_and_check_for_empty_order__
      end
    end
  end
end</pre>
<p>We simply do a check to see if order is empty.  If so, that means our <code>format</code> method was never called, so we just simply need to exit out of the <code>respond</code> method.  I put this in my <code>lib</code> directory and make sure that my app requires this after rails has been loaded.</p>
<h4>Using <code>wrap_respond_to_in</code></h4>
<p>Quite simply all we need to do to use it is to call it, <strong>but we must do so after we have defined all of our methods for which we want to use this technique</strong></p>
<p>.</p>
<pre class="ruby" title="code">class Articles &lt; ApplicationController
  before_filter :find_member, :only =&gt; [:show]

  def show
    format.html
    format.xml { render :xml =&gt; @article.to_xml }
  end

  protected
    def find_member
      @article = Article.find(params[:id])
    rescue ActiveRecord::RecordNotFound
      format.html do
        flash[:error] = "Article was not found"
        redirect_to articles_url
      end
      format.xml { head :status =&gt; 404 }
    end

    wrap_respond_to_in :all
end</pre>
<p>While this is not a complete controller, it does show you how to use it.</p>
<h3>Final Words</h3>
<p>There&#8217;s no reason to put a <code>respond_to</code> call in all of the methods when there is a way around it.  Once I figure out how to get SVN(subversion) working with <a href="http://www.dreamhost.com/,">Dreamhost</a> I am going to put this into a plugin for all to use.</p>
]]></content:encoded>
			<wfw:commentRss>http://shifteleven.com/articles/2006/11/26/drying-up-respond_to/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

