How to Use link_to in Rails

Jan 6, 2015 - 7 min read
How to Use link_to in Rails

Even after 7 years of using Ruby on Rails I still have trouble remembering how to properly use all those options available for the link_to helper. Three out of five times I have to fire up the docs and search for the examples (cause that’s how I like to read the docs).

Having documentation at hand

Using documentation locally is helpful, especially if you can integrate it into your editor. Personally I’m using the ri docs with Emacs and Vim but I guess all those other editors can be configured to access it. If not you can always use ri in your terminal of choice.

Another favourite of mine is the awesome ApiDock. You can even see other people’s comments on the docs and in many cases there you can find examples that are not present in the official docs.

Another very good option (if you’re on a mac) is to use Dash. It’s easy to integrate in your editor or you can just fire it up with a system shortcut whenever you need to access the docs.

That being said, I’m gonna list out a few of the more common examples I use in hopes that they will be useful for both you and me whenever I need to revisit link_to‘s docs again.

The simplest form

The most common and straightforward way of using link_to is to create a barebones (no magic) link. So, assuming your root route points to ‘/’, the way you would use the helper is:

<%= link_to "Home", root_path %>
# => <a href="/">Home</a>

Another common variant is linking to a resource (a user’s profile for example). Let’s say the user’s model is called User and that a @user ivar points to the user record who’s id is 1. Creating a link to the user’s profile will look like the following:

<%= link_to "Profile", user_path(@user) %>
# => <a href="/users/1">Profile</a>

There’s also a shorter version that will do the same thing. It’s got some magic to it (like most things in Rails) but it also looks prettier and there’s less to type (two stones with one bird).

<%= link_to "Profile", @user %>
# => <a href="/users/1">Profile</a>

This is somewhat of a lesser known/used option of link_to but it’s useful nonetheless and it also makes the code more readable. So in those cases where the link text is long and/or ugly, or it doesn’t really fit on a 80 chars line, you can pass the link text inside a block.

To make the example more obvious, I’m gonna do a before and after kind of thing.


<%= link_to "<span class='home-link'>Home</span>".html_safe, root_path %>
# => <a href="/"><span class="home-link">Home</span></a>


<%= link_to root_path do %>
  <%= content_tag :span, "Home", :class => "home-link" %>
<% end %>
# => <a href="/"><span class="home-link">Home</span></a>

In this case I’ve purposely chosen a less uglier link text, but usually the link text will be something like an image tag or a span with an icon inside it (or any other ugly html code you can think of).

Another very common task you’ll use is to add a html class or id to your links.

<%= link_to "Section", root_path, :class => "my-class", :id => "my-id" %>
# => <a href="/" class="my-class" id="my-id">Section</a>

Calling the destroy action of a REST-ful controller requires a DELETE request and that can be easily achieved by passing the :method => :delete hash as an option to the link_to helper.

<%= link_to "Remove", @user, :method => :delete %>
# => <a rel="nofollow" data-method="delete" href="/users/1">Remove</a>

Note that the rel="nofollow" is auto-magically added by Rails as an SEO bonus.

Require confirmation for deleting a record

You will probably want some sort of confirmation when removing objects to prevent accidental deletes. The easiest way to add that is with a simple javascript alert box that will ask the user to confirm his delete request.

<%= link_to "Remove", @user, :method => :delete, :data => {:confirm => "You Sure?"} %>
# => <a data-confirm="You Sure?" rel="nofollow" data-method="delete" href="/users/1">Remove</a>

It might be that you want to make your links prettier or that you want to have some nice buttons, or even a logo click-able or whatever the reason for using click-able images is, you’ll want to add your image inside the link. Making an image link-able is pretty straight forward. Just add the image_tag where the link text would go and you’re done.

<%= link_to image_tag('logo.png'), root_path %>
# => <a href="/"><img src="/assets/logo-c88948e05e11587af2c23747862ca433.png" alt="Logo"></a>

You can also pass the image in a block if you like that style better.

<%= link_to root_path do %>
  <%= image_tag('logo.png') %>
<% end %>
# => <a href="/"><img src="/assets/logo-c88948e05e11587af2c23747862ca433.png" alt="Logo"></a>

A nice side-effect of using the image_tag helper is that it will add the asset digest to your image.

Adding an alt attribute to the image

As you’ve seen in the previous example, I didn’t specify an alt attribute but the link_to helper generated one. The generated alt tag is just the name of the image file, capitalized. In case you want (and you should want) to override the alt attribute, it’s very easy to do; just add your own alt attribute like so:

<%= link_to image_tag('logo.png'), root_path, :alt => "MyLogo" %>
# => <a href="/"><img src="/assets/logo-c88948e05e11587af2c23747862ca433.png" alt="MyLogo"></a>

Alt attributes are beneficial for SEO purposes and they also aid those visitors who use text readers or non graphical browsers.

There are times when you might want to link to an image (not necessarily with an image). This can be confusing because you need your image to contain the image digest generated by the asset pipeline. There’s a helper that provides just that and it’s called image_path.

<%= link_to "Logo", image_path('logo.png') %>
# => <a href="/assets/logo-c88948e05e11587af2c23747862ca433.png">Logo</a>

You might need to point to a specific section (anchor) in the page which you can identify by it’s dom ID. So let’s say on the target page we have a section that has the id="interesting-section". In order to point our link to that section, we’ll need to add the anchor to the generated link.

<%= link_to "Section", root_path(:anchor => "interesting-section") %>
# => <a href="/#interesting-section">Section</a>

You can add the :remote => true option to the link to tell Rails that you want to handle the link via javascript. This option will automatically send an ajax request (handled via the jQuery UJS adapter).

<%= link_to "Ajax", root_path, :remote => true %>
# => <a data-remote="true" href="/">Ajax</a>

For a good user experience and because you’ll want your user not to leave your website if possible, you should make all your external links open in a separate tab or window. You can achieve this by using the target="_blank" html attribute which in Rails speak will look like this:

<%= link_to "Google", "", :target => "_blank" %>
# => <a target="_blank" href="">Google</a>

POST-ing using link_to

Sending a post request via a link is something that the html <a href> cannot do. You can only use it to make GET requests, not POST. That being said, Rails has some magic tricks for you.

By providing the :method => :post option, Rails will create a form and submit it via javascript. Note that you need the jquery-rails gem for this to work, if you don’t have it, there won’t be any magic happening and your links will default to a GET request.

<%= link_to "Post", root_path, :method => :post %>
# => <a rel="nofollow" data-method="post" href="/">Post</a>

Adding more params to the POST request

<%= link_to "Create User", users_path(:email => "", :password => "secret"), :method => :post %>
# => <a rel="nofollow" data-method="post" href="/users?">Create User</a>


These are some of the more common ways I’ve used link_to but I’m sure there are many others. So if you have any other examples I could add to the article please let me know in the comments section below.

12 Project Ideas
Cezar Halmagean
Software development consultant with over a decade of experience in helping growing companies scale large Ruby on Rails applications. Has written about the process of building Ruby on Rails applications in RubyWeekly, SemaphoreCI, and Foundr.