Merb CRUD - ie: how to properly destroy things

By now most Rails developers have come to know and love (or not?) RESTful resources and the controller code that implements them. For the most part Merb’s implementation of resources will be familiar and adheres to the same convention - GET safe creates, updates, destroys, a single base URI for a single resource, etc.

One small difference with Merb’s resources is in regards to the implementation of destroying a resource. In Rails you run into this weird situation where performing a destroy on a record via a browser is nearly impossible without relying on Javascript to create that ugly dynamic form that gets triggered by using the link_to method and passing “:method => :delete”.

  <%= link_to "Delete Image", { :action => "delete", :id => @image.id }, 
      :confirm => "Are you sure?", :method => :delete %>
  # => <a href="/testing/delete/9/" onclick="if (confirm('Are you sure?')) 
  { var f = document.createElement('form'); f.style.display = 'none'; 
  this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;
  var m = document.createElement('input'); m.setAttribute('type', 
  'hidden'); m.setAttribute('name', '_method'); m.setAttribute('value', 
  'delete'); f.appendChild(m);f.submit(); };return false;">Delete Image</a>

Not ideal IMHO.

The other option in Rails is to create the delete link manually as a button or submit tag in its own little form - personally i use this approach because it is does not require Javascript to work, but I have never liked cluttering the DOM with tons of little forms.

Merb, has a different answer - one that tripped me up until I realized what was going on: use an intermediary page.

In Merb a GET request to /users/1/delete (with the users resource declared in the router) will route to the “delete” method in the users controller. The purpose of this page is exactly the same as the “new” and “edit” methods - to provide an HTML form to someone (or something) interacting with the resource via a web browser. The idea is that in a non-Javascript world  you can still implement an “are you sure?” type confirmation AND get the added benefit of providing a GET safe destroy. If the developer would like to mimic the Rails inline javascript delete form style html link it is trivial to do so, but with the added benefit of graceful degradation (ie: still works without javascript).

The ideal solution in my humble opinion is first implement the full delete page with destroy html form and “Are you sure?” confirmation message and then after that is working (and tested). Next you would implement an Ajax destroy button that posts a DELETE request and will be routed directly to the destroy method in the controller. This way you get a great user experience when using a fully featured web browser, but are still able to use the app if you happen to not have javascript.

blog comments powered by Disqus