Search code examples
ruby-on-railsrubylink-to

How does Rails' link_to work?


From the docs:

link_to "Profile", profile_path(@profile)
# => <a href="/profiles/1">Profile</a>
link_to "Profile", @profile
# => <a href="/profiles/1">Profile</a>

There's a lot going on here. First, there is the method #profile_path which gets generated for the Profile resource. These types of methods get generated all the time.

  • How does that work?
  • Where would I read the documentation for a method that gets generated?

Then in the second example, the profile_path method is omitted.

  • Does rails know it's in a view associated with the Profile resource?
  • How does it know?

Also from the docs, the method signature for link_to:

link_to(body, url_options = {}, html_options = {})

Also here there is a lot going on. From the perspective of ruby link_to is a method that takes three positional arguents, two of which are optional. But the last two are hashes, so it's a little tricky to differentiate between the two unless we explicitly use curlies. So we need to be careful about whether trying to set the url_options or html_options.

  • What's the difference between url_options and html_options?
  • When and why would you use each?
  • Can you provide a simple example?

Solution

  • You can see all of your routes by running rake routes in your app root directory. Example:

                          Prefix Verb      URI Pattern                                                             Controller#Action
                    negotiations GET       /negotiations(.:format)                                                 negotiations#index
                                 POST      /negotiations(.:format)                                                 negotiations#create
                 new_negotiation GET       /negotiations/new(.:format)                                             negotiations#new
                edit_negotiation GET       /negotiations/:id/edit(.:format)                                        negotiations#edit
                     negotiation GET       /negotiations/:id(.:format)                                             negotiations#show
                                 PATCH     /negotiations/:id(.:format)                                             negotiations#update
                                 PUT       /negotiations/:id(.:format)                                             negotiations#update
                                 DELETE    /negotiations/:id(.:format)                                             negotiations#destroy
    

    Thus you can use any of these prefixes with _path or _url at the end. I won't go into details on _url now as it's not directly relevant to your question.

    Rails is able to map any object that you pass into link_to by its model. It actually has nothing to do with the view that you use it in. It knows that an instance of the Profile class should map to the /profiles/:id path when generating a URL. The precondition for this is that you're declaring the Profile routes in your routes.rb using the resources tag, e.g. resources :profiles.

    url_options is for passing a URL or any options for it. It often involves magic that Rails has to perform first before the HTML can be rendered.

    html_options is for passing settings to the link tag itself. The actual path itself goes in url_options, whereas id, class, etc. all go in html_options. Here's an example:

    link_to "Profile", @profile, class: 'button'
    

    The docs are a great reference on this. Check them out: http://apidock.com/rails/ActionView/Helpers/UrlHelper/link_to