Rails DELETE requests with JQuery

May 20, 2009

When I write admin controls for for a Rails app, I like to make the delete links just fire off an Ajax request, delete the record, and remove the element from the page. This is easy with the Rails default setup using Prototype. All you have to do is use link_to_remote with a :method => 'delete' to make Rails do all the work. The problem is, this is the code that Rails generates:

<%= link_to_remote("Delete", :url => admin_post_path(post), :method => :delete) %>
<!- turns into: -->
<a href="#" onclick="new Ajax.Request('/users/63', {asynchronous:true, evalScripts:true, method:'delete'});); return false;">Delete</a>

While this isn't terrible, it's certainly not very pretty. Surely we can make the code cleaner and simpler!

Well, we've recently switched to using JQuery for all of our new apps at Plexus. Unless you use the JRails plugin, the link_to_remote helper no longer works when using JQuery. I figured this would be a good time to switch the remote calls to be handled separately by JavaScript, instead of spitting out a ton of script in the HTML.

It's easy to just hijack links via JavaScript and have them submit via Ajax, but how do we handle REST requests that require the DELETE method?

I decided to just add a specific class to all links that I wanted to be hijacked by JavaScript, then add the code in my js file to handle the links with Ajax. My DELETE links would look like this:

<!- Link that uses DELETE method -->
<%= link_to 'Delete', entry_path(entry), :class => 'remote-delete' %>

The key to hijacking the link is to include the hidden _method attribute set to 'delete'. My JavaScript to hijack the link would look like this:

$(document).ready(function() {
  $('a.remote-delete').click(function() {
    // we just need to add the key/value pair for the DELETE method
    // as the second argument to the JQuery $.post() call
    $.post(this.href, { _method: 'delete' }, null, "script");
    return false;

This converts every link that has the remote-delete class to an Ajax request with the DELETE method!

Tagged: jquerydeleterest