<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>opensoul.org - Tip: Overriding link_to to accept a block Changes</title>
  <id>tag:opensoul.org,2009:/2006/8/4/tip-overriding-link_to-to-accept-a-block/changes</id>
  <generator uri="http://mephistoblog.com" version="0.8.0">Mephisto Drax</generator>
  <link href="http://opensoul.org/2006/8/4/tip-overriding-link_to-to-accept-a-block/changes.xml" rel="self" type="application/atom+xml"/>
  <link href="/2006/8/4/tip-overriding-link_to-to-accept-a-block" rel="alternate" type="text/html"/>
  <updated>2006-10-25T02:58:58Z</updated>
  <entry xml:base="http://opensoul.org/">
    <author>
      <name>brandon</name>
    </author>
    <id>tag:opensoul.org,2006-10-25:156:2</id>
    <published>2006-08-04T16:10:00Z</published>
    <updated>2006-10-25T02:58:58Z</updated>
    <link href="http://opensoul.org/2006/8/4/tip-overriding-link_to-to-accept-a-block" rel="alternate" type="text/html"/>
    <title>Tip: Overriding link_to to accept a block</title>
<content type="html">&lt;p&gt;You&#8217;d think I would get tired of saying this: Ruby is amazing! On numerous occasions in recent weeks, I&#8217;ve needed some complex logic or multiple lines worth of code to determine the title for my &lt;code&gt;link_to&lt;/code&gt; calls. For example:
&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;erb&quot;&gt;&amp;lt;%= link_to(course.full? ?
    &quot;&amp;lt;span class=&quot;full&quot;&amp;gt;#{course.name}&amp;lt;/span&amp;gt;&quot; :
    course.name + course.almost_full? ?
        &quot;&amp;lt;span class=\&quot;available\&quot;&amp;gt;&quot; + 
            &quot;(#{pluralize course.capacity, 'spot'} available)&amp;lt;/span&amp;gt;&quot; :
        &quot;&amp;lt;span class=\&quot;enrolled\&quot;&amp;gt;&quot; +
            &quot;(#{pluralize course.enrolled.count, 'student'} enrolled)&amp;lt;/span&amp;gt;&quot;,
    :action =&amp;gt; 'show', :id =&amp;gt; course)

%&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The output of this would be something like:

&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;&amp;lt;a href=&quot;/courses/show/1&quot;&amp;gt;&amp;lt;span class=&quot;full&quot;&amp;gt;Cognitive Ergonomics&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/pre&gt;
or
&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;&amp;lt;a href=&quot;/courses/show/1&quot;&amp;gt;Cognitive Ergonomics &amp;lt;span class=&quot;enrolled&quot;&amp;gt;(3 students enrolled&amp;lt;/span&amp;gt;)&amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/pre&gt;
or
&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;&amp;lt;a href=&quot;/courses/show/1&quot;&amp;gt;Cognitive Ergonomics &amp;lt;span class=&quot;available&quot;&amp;gt;(3 spots available&amp;lt;/span&amp;gt;)&amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;depending on the conditions.&lt;/p&gt;&lt;/p&gt;


&lt;p&gt;Now, one could argue that I should just break it out into a bunch of if/else branches, and call &lt;code&gt;link_to&lt;/code&gt; for each one, but&#8230;this is Ruby, there&#8217;s got to be a way to keep it &lt;acronym title=&quot;Don't Repeat Yourself&quot;&gt;&lt;span class=&quot;caps&quot;&gt;DRY&lt;/span&gt;&lt;/acronym&gt;!  Especially if my &lt;code&gt;link_to&lt;/code&gt; arguments are lengthy, which is often the case with &lt;code&gt;link_to_remote&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The solution I came up with today involves adding the following to one of your view helpers, like &lt;code&gt;ApplicationHelper&lt;/code&gt;:
&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def link_to(*args, &amp;amp;block)
  if block_given?
    concat super(capture(&amp;amp;block), *args), block.binding
  else
    super(*args)
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As &lt;a href=&quot;http://codefluency.com/&quot;&gt;Bruce Williams&lt;/a&gt; pointed out to me, due to the way modules are mixed in, calling &lt;code&gt;super&lt;/code&gt; on an overridden method will end up calling the original class method.  So, if a block is passed, it will capture the result of the block and pass it on as the first argument along with the other arguments to the original link_to method.  If no block is given, it will simply pass on all the arguments to the original link_to method&lt;/p&gt;
&lt;p&gt;The result is that now I can continue to use &lt;code&gt;link_to&lt;/code&gt; in the traditional fashion, or for those tricky situations, just pass a block to it, like:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;erb&quot;&gt;&amp;lt;% link_to(:action =&amp;gt; 'show', :id =&amp;gt; course) do %&amp;gt;
    &amp;lt;% if course.full? -%&amp;gt;
        &amp;lt;span class=&quot;full&quot;&amp;gt;&amp;lt;%= course.name %&amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;% else -%&amp;gt;
        &amp;lt;%= course.name %&amp;gt;
        &amp;lt;% if course.almost_full? %&amp;gt;
            &amp;lt;span class=&quot;available&quot;&amp;gt;
                (&amp;lt;%= pluralize course.capacity, 'spot' %&amp;gt; available)
            &amp;lt;/span&amp;gt;
        &amp;lt;% else %&amp;gt;
            &amp;lt;span class=&quot;enrolled&quot;&amp;gt;
                (&amp;lt;%= pluralize course.enrolled.count, 'student' %&amp;gt; enrolled)
            &amp;lt;/span&amp;gt;
        &amp;lt;% end %&amp;gt;
    &amp;lt;% end -%&amp;gt;
&amp;lt;% end %&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now I can do all the branching that I want with if/else statements, and I only have to declare my link_to parameters once&lt;/p&gt;

&lt;p&gt;If only I could figure out how to alias this method in the helper, it could work with all the variations of the link_to helpers (well, technically, any helper that you want to pass a block in as the first argument). Calling &lt;code&gt;alias_method :link_to_remote, :link_to&lt;/code&gt; doesn&#8217;t work, and &lt;code&gt;define_method&lt;/code&gt; doesn&#8217;t seem to let me get the block. Anyone have any ideas?&lt;/p&gt;</content>  </entry>
  <entry xml:base="http://opensoul.org/">
    <author>
      <name>brandon</name>
    </author>
    <id>tag:opensoul.org,2006-10-23:129:1</id>
    <published>2006-08-04T16:10:04Z</published>
    <updated>2006-10-23T03:44:15Z</updated>
    <link href="http://opensoul.org/2006/8/4/tip-overriding-link_to-to-accept-a-block" rel="alternate" type="text/html"/>
    <title>Tip: Overriding link_to to accept a block</title>
<content type="html">&lt;p&gt;You&#8217;d think I would get tired of saying this: Ruby is amazing! On numerous occasions in recent weeks, I&#8217;ve needed some complex logic or multiple lines worth of code to determine the title for my &lt;code&gt;link_to&lt;/code&gt; calls. For example:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&amp;amp;lt;%= link_to(course.full? ?
    &quot;&amp;amp;lt;span class=&quot;full&quot;&amp;amp;gt;#{course.name}&amp;amp;lt;/span&amp;amp;gt;&quot; :
    course.name + course.almost_full? ?
        &quot;&amp;amp;lt;span class=\&quot;available\&quot;&amp;amp;gt;&quot; + 
            &quot;(#{pluralize course.capacity, 'spot'} available)&amp;amp;lt;/span&amp;amp;gt;&quot; :
        &quot;&amp;amp;lt;span class=\&quot;enrolled\&quot;&amp;amp;gt;&quot; +
            &quot;(#{pluralize course.enrolled.count, 'student'} enrolled)&amp;amp;lt;/span&amp;amp;gt;&quot;,
    :action =&amp;amp;gt; 'show', :id =&amp;amp;gt; course)

%&amp;amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The output of this would be something like:

&lt;pre&gt;&lt;code&gt;
&amp;amp;lt;a href=&quot;/courses/show/1&quot;&amp;amp;gt;&amp;amp;lt;span class=&quot;full&quot;&amp;amp;gt;Cognitive Ergonomics&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;/a&amp;amp;gt;
&lt;/code&gt;&lt;/pre&gt;
or
&lt;pre&gt;&lt;code&gt;
&amp;amp;lt;a href=&quot;/courses/show/1&quot;&amp;amp;gt;Cognitive Ergonomics &amp;amp;lt;span class=&quot;enrolled&quot;&amp;amp;gt;(3 students enrolled&amp;amp;lt;/span&amp;amp;gt;)&amp;amp;lt;/a&amp;amp;gt;
&lt;/code&gt;&lt;/pre&gt;
or
&lt;pre&gt;&lt;code&gt;
&amp;amp;lt;a href=&quot;/courses/show/1&quot;&amp;amp;gt;Cognitive Ergonomics &amp;amp;lt;span class=&quot;available&quot;&amp;amp;gt;(3 spots available&amp;amp;lt;/span&amp;amp;gt;)&amp;amp;lt;/a&amp;amp;gt;
&lt;/code&gt;&lt;/pre&gt;
depending on the conditions.&lt;/p&gt;

&lt;p&gt;Now, one could argue that I should just break it out into a bunch of if/else branches, and call &lt;code&gt;link_to&lt;/code&gt; for each one, but&#8230;this is Ruby, there&#8217;s got to be a way to keep it &lt;acronym title=&quot;Don't Repeat Yourself&quot;&gt;&lt;span class=&quot;caps&quot;&gt;DRY&lt;/span&gt;&lt;/acronym&gt;!  Especially if my &lt;code&gt;link_to&lt;/code&gt; arguments are lengthy, which is often the case with &lt;code&gt;link_to_remote&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The solution I came up with today involves adding the following to one of your view helpers, like &lt;code&gt;ApplicationHelper&lt;/code&gt;:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
def link_to(*args, &amp;amp;amp;block)
  if block_given?
    concat super(capture(&amp;amp;amp;block), *args), block.binding
  else
    super(*args)
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As &lt;a href=&quot;http://codefluency.com/&quot;&gt;Bruce Williams&lt;/a&gt; pointed out to me, due to the way modules are mixed in, calling &lt;code&gt;super&lt;/code&gt; on an overridden method will end up calling the original class method.  So, if a block is passed, it will capture the result of the block and pass it on as the first argument along with the other arguments to the original link_to method.  If no block is given, it will simply pass on all the arguments to the original link_to method&lt;/p&gt;
&lt;p&gt;The result is that now I can continue to use &lt;code&gt;link_to&lt;/code&gt; in the traditional fashion, or for those tricky situations, just pass a block to it, like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&amp;amp;lt;% link_to(:action =&amp;amp;gt; 'show', :id =&amp;amp;gt; course) do %&amp;amp;gt;
    &amp;amp;lt;% if course.full? -%&amp;amp;gt;
        &amp;amp;lt;span class=&quot;full&quot;&amp;amp;gt;&amp;amp;lt;%= course.name %&amp;amp;gt;&amp;amp;lt;/span&amp;amp;gt;
    &amp;amp;lt;% else -%&amp;amp;gt;
        &amp;amp;lt;%= course.name %&amp;amp;gt;
        &amp;amp;lt;% if course.almost_full? %&amp;amp;gt;
            &amp;amp;lt;span class=&quot;available&quot;&amp;amp;gt;
                (&amp;amp;lt;%= pluralize course.capacity, 'spot' %&amp;amp;gt; available)
            &amp;amp;lt;/span&amp;amp;gt;
        &amp;amp;lt;% else %&amp;amp;gt;
            &amp;amp;lt;span class=&quot;enrolled&quot;&amp;amp;gt;
                (&amp;amp;lt;%= pluralize course.enrolled.count, 'student' %&amp;amp;gt; enrolled)
            &amp;amp;lt;/span&amp;amp;gt;
        &amp;amp;lt;% end %&amp;amp;gt;
    &amp;amp;lt;% end -%&amp;amp;gt;
&amp;amp;lt;% end %&amp;amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;hmm&#8230;this looks a lot cleaner in TextMate with syntax highlighting.&lt;/blockquote&gt;
&lt;p&gt;Now I can do all the branching that I want with if/else statements, and I only have to declare my link_to parameters once&lt;/p&gt;

&lt;p&gt;If only I could figure out how to alias this method in the helper, it could work with all the variations of the link_to helpers (well, technically, any helper that you want to pass a block in as the first argument). Calling &lt;code&gt;alias_method :link_to_remote, :link_to&lt;/code&gt; doesn&#8217;t work, and &lt;code&gt;define_method&lt;/code&gt; doesn&#8217;t seem to let me get the block. Anyone have any ideas?&lt;/p&gt;</content>  </entry>
</feed>
