Ruby On Rails Beginners - Demystify the magic. Part 3: The link_to method
Published: 2023-04-26 15:13:19

In our two last posts, we went over how ruby methods in Rails are usually written without parentheses, and that they really are just plain old ruby methods.

Now we are going to dive into the Rails documentation to get a better understanding of what the link_to helper method is used.

## Finding the documentation

Visit https://edgeapi.rubyonrails.org/ and bookmark this page, if you haven't already.

Note: when you google Rails methods, be aware that sometimes it will take you to an older version of the API docs.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mg28nsqppqc9btq4rp9i.png)

In the top left search field type in link_to, not only does it give us the link_to, but it also shows us there's a `link_to_if` helper and some `link_to_unless` helpers too! Let's stick to the link_to helper for now.

https://edgeapi.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to

## Breaking it down

To start lets look at the breakdown of an anchor tag in HTML
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5gp6dea08hohq4n1iuek.jpg)

Pretty straightforward.

Now the Rails docs start off with this first line.

`link_to(name = nil, options = nil, html_options = nil, &block)`

That looks OK, it's just a method that takes in 4 arguments, which are effectively 3 arguments, with the &block meaning when we call the method we have the option to follow it with a `do` block (we will cover this later).

Let's take a look at each of the arguments and see what they do.

### name = nil
In the link_to description, it says "Creates an anchor element of the given name using a URL created by the set of options."

Straight off, this sounds a little bit cryptic. "name" or "options" don't really make sense in the context of an HTML anchor link.

Luckily if we continue reading, we get a little bit more context.

It breaks it down into the context of the actual output, so we see that 
``link_to(name = nil, options = nil, html_options = nil, &block)`
is actually
`link_to(body, url, html_options = {})`

So the `name = nil` is actually the body of the anchor link, ie: the text between the `<a>` and `</a>` tags. 

Also, if it's not passed in as an argument, it defaults to nil (that's what the `= nil` means). But when would you ever create an empty anchor element? Well, you wouldn't, but we need this for when we pass the method a block, which we will cover later.

### options = nil
Again, `options = nil` doesn't really tell us much about what this is for, but looking at the example we see that the second argument is the URL `link_to(body, url, html_options = {})`. We will usually put in a string of the URL we want or we use a path helper thats rails gives. eg: `root_path`, which will return a string of our site's root path. Pretty easy so far.

### html_options = nil
Now this one is a little trickier. Even the given example doesn't really give us any more information.

To figure out what this is let's actually experiment with the method in a Rails app.

Let's start off with a basic link that has a body and a URL.
`<%= link_to "Dev Blog", "http://dev.to" %>`

This will return an anchor link like this
`<a href="http://dev.to">Dev Blog</a>`

OK, so let's see what the html_options do, remembering that we need to pass in a hash, so each element has a key with a value.
`<%= link_to "Dev Blog", "http://dev.to", {beep: "boop"} %>`

returns
`<a beep="boop" href="http://dev.to">Dev Blog</a>`

So html_options allows us to create attributes for our anchor tag. We can add a class, an id, and any other attribute our link needs. 

`<%= link_to "Dev Blog", "http://dev.to", {class: "link primary", target: "_blank"} %>`

returns
`<a class="link primary" target="_blank" href="http://dev.to">Dev Blog</a>`

note: `target="_blank"` will open the link in a new window.

We can even change the request from a `GET` to any of the other request methods. (`GET` being the default action of a link)
`<%= link_to "Delete", "listing/24",{method: :delete, class: 'btn-secondary'} %>`

returns:
`<a class="btn-secondary" rel="nofollow" data-method="delete" href="/listing/24">Delete</a>`

Now here you will notice that the method attribute has turned into `data-method`, Rails sees you are changing the method attribute and automatically prefixes it with `data-`.
This is something that is required for Hotwire and Turbo to work. 

You also see that now there is a `rel="nofollow"` attribute. Again, this is something that Rails adds for us automatically and this tells search engines to ignore the link when they are indexing your website. There's no page or content when you click on a link that sends a delete request, so there's nothing for a search engine to index.

See more details here:
https://backlinko.com/nofollow-link

## &block
Now this is easy to implement but a little tricky to understand how it's doing it, so today let's just stick with the implementation side of things. (Look up ruby callback methods if you want a better understanding of how this works.)

Sometimes we need a link to be more than just a text link, like a button or a card component, this is where the &block comes in.

So now when we call the link_to method, we follow it with a `do` block, with the required HTML written inside the block.

example:
`<%= link_to "http://dev.to" do %>
    <div class="card">
      This is a link block
    </div>
<% end %>`

returns:
`<a href="http://dev.to">
    <div class="card">
      This is a link block
    </div>
</a>`

This allows us to make card components that are links themselves. Pretty cool.

It's all pretty clever stuff but can be a little confusing if you don't know what it's doing.

## One last thing
Just as we covered in Part 1, there's also a way of writing the link_to method arguments without wrapping the options in curly braces. So instead of writing this

`<%= link_to "Dev Blog", "http://dev.to", {class: "link primary", target: "_blank"} %>`

you can write, and will quite often see this:
`<%= link_to "Dev Blog", "http://dev.to", class: "link primary", target: "_blank" %>`

Again, Ruby is smart enough to know that if you have a method that requires 3 arguments, and when we call it we pass in 6 arguments, all the arguments after the second argument will become a hash that gets passed in as the third argument.

I prefer to use the curly braces, as it makes it more explicit when you are reading the code.

## Conclusion
Now we know how to use the API docs and we understand the link_to helper method a little bit better. Next, we will look at the actual source code for Rails to get an even better understanding.