MarkUs Blog

MarkUs Developers Blog About Their Project

MarkUs: link_to() and button_to() recommended usage

without comments

This term I spent a lot of time working on removing some of our legacy code that involved using the Prototype helper link_to_remote(). The recommended way in Rails 3 is to use the standard link_to() which itself has support for :remote calls. During my work here, I stumbled along a couple of problems which actually forced me to dig deeper and learn more about recommended practices.

In particular, I want to write about the recommended/proper usage of link_t0() versus button_to(). Although at first glance they might seem like they do similar things, they actually are quite different fundamentally, and should be used for different operations.


A helper to create a link on a page that simply redirects the user to a new path in the application. Links, in reality are meant to be used for navigation (GET requests). For example, it makes sense to have a link going from the Assignments page, to the Users page, since data is only being retrieved and not updated during the navigation. However, Rails also supports methods other than GET through JavaScript which makes it possible to bypass the navigation-only limitation. Although this works, button_to() is still better for these requests, as explained in the next section.

Notes: There is also support for AJAX-ified links through specifying :remote => true and adding separate unobstrusive JavaScript drivers to perform operations before, during and after the AJAX call. 


Compared to link_to(), button_to() actually generates a form for itself and when the user clicks the button, the form is submitted through the generated URL. This is definitely the recommended option for any deletion, creation or modification requests. The reason is that if modification of data can be accessed through a simple link, then search bots or accelerators (or “crawlers” as many call them) can potentially change your data, which can become a very dangerous security issue. Also, if the user has JavaScript disabled for some reason, then link_to()’s :method will default to GET, no matter what the code specifies.

Notes: If you decide to change a link_to() to a button_to(), make sure that it is not already in a form. Because button_to() generates a form, the nested forms will result in erratic behaviour. 

All in all, the main lesson to take away is that link_to() should be kept to GET requests / application navigation, while button_to() is more suited to data modification (POST, PUT, DELETE). There is a reason why link_to() defaults to GET, and button_to() defaults to POST !

Written by hwu

March 18th, 2012 at 5:01 pm

Leave a Reply