How to use link_to as a wrapper

Even if I was born as a Frontend Developer I have been working on Ruby on Rails projects more and more lately, and allow me to say that I really enjoy the experience.

I plan to write more and more about this framework, even if there are loads of good resources online, but this is my place and you can read my take on it.

Today I want to write about the link_to helper that came out of the box in any Rails project.

I find it a great helper because it lets you build a link in no time:

<%= link_to "All Articles", articles_path %>

With this single line of code Rails will generate a standard anchor HTML that looks like:

<a href="/articles">All Articles</a>

As you can see we are comparing a one-liner with another one-liner, so why should you learn a new way to do the same thing that you where used to do in HTML?

Fare question and my answer is simply: because you want to leverage the Rails way and write as less code as possible.

Let me explain it separating my answer.

Leverage the Rails way

link_to is a powerful helper that accepts a lot of interesting attributes, in the above example you see that we're just passing the href attribute but this helper is more powerful that that.

While invoking it you can pass classes, data attributes, HTTP methods with confirmation options and basically anything useful you can think of inside a link. Just to give you an example let's look at how we can create a link that will delete a single article:

<%= link_to "Delete article",
class: "delete_btn",
method: "delete",
{ confirm: "Are you sure?", disable_with: "Processing" }

Rails will go ahead and will threat the link to send a REST delete instruction that will allow us to delete the connected article, connected via the @article instance btw.

If you plan to do something like this with a plain HTML a you should get ready for a lot of pain.

Write as less code as possible

Since the first time I met the Ruby on Rails framework, as well as the Ruby language, I noticed that more than in other languages here the developers like to write as less as possible. Interesting enough the code that we write with Ruby is also incredibly simple to read.

Let's take the opposite approach, let's first write an HTMLish code that check if the user can edit a specific article and provide a link to do so:

<% if user_can_edit %>
<a href="<%= edit_article_path(@article) %>">Edit "<%= @article.title %>"</a>
<% end %>

Here you have it but did you notice how many times we had to write a Ruby block? We have one for open the if, one to generate the path, one to include the title of the article and even one for ending our check.

Maybe it is just me that I am not yet used to write <% %> but tbh to me it looks like a waste of time writing all of this.

With the link_to helper we can write all the above in a more elegant way:

<%= link_to "Edit #{@article.title}", edit_article_path(@article) if user_can_edit %>

The HTML example is now a one-liner and let me say that I felt in love with the ability to add my conditions at the end of the declaration, really that's the first feature I wanted to shout out loud when I first met!

Use link_to as a container

I do not want to convince you to write link_to, if you are reading this article probably you already leverage its power but you are facing a little problem that it is hard to find an answer online.

How to use link_to as container of a complex HTML block?

I have been there too and I read lots of docs, answers and articles but it wasn't until I experimented with it that I totally got it.

Let's say the designer will give you a card component that you need to create. You know one of the most common elements that you see on sites in the last decade.

<article class="card">
<img class="card__image" />
<heading class="card__heading">
<h3 class="card__title">Title</h3>
<time class"card__published">1-1-1111</time>
<section class="card__description">
<footer class="card__footer">
<a class="card__button" href="#"> ... </a>

This component has a title and a button, beside all other elements, and you make both of them a simple link but then someone from the design or PM team say something like "Why don't we make clickable all the area of the card?", and now you have to remove the link_to used for the title and button and find a way to use it as a wrapper.

My approach to it has been the following:

link_to card_path(,
class: 'card' do
<!-- Card code -->
<% end %>

This example is really simple but I think you get the point, you omit the text that you should pass as a link and apply the do-end block definition. Everything that's inside it will became the body of our link.

Don't be afraid to put even more stuff!

I started to look around because all the example I found regarding this approach weren't using neither the class declaration, it was just a link.

In my specific case I also had to pass some data- attributes (welcome Stimulus) and even a style resulting in the following:

link_to your_path,
class: 'your_class',
style: "your_stiles",
data: { action: 'your_action' } do

I am not saying that this is the best approach in the world, it is just my approach that it solve my need. If you want to share with me your thoughts you can do it on Twitter or even with a PR in the repo of the site 😉

Thanks for reading it.

Soon I'll write something here...