Friday, December 2, 2011

To link or not to link - Rails link helpers unveiled

One of the first things you learn when you create Action View templates in Ruby on Rails is how to link to other urls and actions. The basic syntax is

link_to 'Change my life', edit_life_path(@my_life)

But maybe you haven’t heard of link_to’s little brothers and sisters that come in handy really often:

I will cover each of these underestimated little friends in the following:

This helper renders the link only under certain circumstances, otherwise it just shows the link text.

Given you let your logged in users do some magical stuff. But even when they’re not logged in you want them to know that it is possible to do some magical stuff:

link_to_if user_logged_in?, "Do magical stuff!", magical_stuff_path

This way you show logged in users a Do magical stuff link

<a href="/magical_stuff">Do magical stuff</a>

and other users just a plain Do magical stuff text.

Admittedly, some users might get annoyed trying to do magical stuff without having a clue how to. Fortunately Action View provides a solution:

link_to_if user_logged_in?, "Do magical stuff!", magical_stuff_path do
  link_to "Log in to do magical stuff", log_in_path
end

The block is executed in case the condition is not met. So if user aren’t logged in, you give them a hint how to do magical stuff. Now everybody’s happy eventually.

The counterpart to link_to_if is link_to_unless. You can use the simple version that will either render a link or just text

link_to_unless drunk?, "Have a beer", drink_beer_path

but also the advanced version using a block:

link_to_unless drunk?, "Have a beer", drink_beer_path do
  link_to "Dance like crazy", crazy_dancing_path
end

This special variant of link_to_unless renders a link unless it links to the current page. The main purpose of it is a navigation:

<nav>
  <ul>
    <li><%= link_to_unless_current 'Go back home', home_path %></li>
    <li><%= link_to_unless_current 'Get cookies', cookies_path %></li>
  </ul>
</nav>

When you’re on the home page, Go back home is rendered as plain text whereas Get cookies is still a link to delicious cookies_path:

<nav>
  <ul>
    <li>Go back home</li>
    <li><a href="/cookies">Get cookies</a></li>
  </ul>
</nav>

Also link_to_unless_current accepts a block, so we could reduce the above code to

<nav>
  <ul>
    <li>
      <%= link_to_unless_current 'Go back home', home_path do
        link_to_unless_current 'Get cookies', cookies_path
      end %>
    </li>
  </ul>
</nav>

I hope you found this useful, if you have any questions or suggestions just leave me a comment!

4 comments:

  1. good work Clemens..Thanks for digging so deep

    By,
    Dharin Rajgor

    ReplyDelete
  2. Thanks I'll definitely try the link_to_if . Once question not really Rails related; how did you do the code comments such that the line numbers don't get highlighted when I copy the text? Cheers Walter

    ReplyDelete
  3. Hey Walter, check out http://alexgorbatchev.com/SyntaxHighlighter. It converts the pre-elements automatically to tables, where the line numbers are in the left column and the code is in the right column. This way you can copy just the right column’s text.

    ReplyDelete
  4. Thanks for the post Clemens. I'm a beginner hobbyist and this is really neat.

    ReplyDelete

 
DreamHost coupon code