Skip to content


Subversion checkout URL

You can clone with
Download ZIP


RESTful frameworks should have a delete path and #delete controller method #4234

nbt opened this Issue · 16 comments

9 participants


The three (conceptual) actions that modify a database table are CREATE, MODIFY and DELETE. The first two -- CREATE and MODIFY -- are handled nicely in the RESTful framework, the DELETE action is not. To explain:

The contract of #new is to respond with a form that when submitted calls #create to modify the database. The #new request is idempotent and can use GET, the #create method actually modifies the database and uses POST.

Similarly, the contract of #edit is to generate a form that when submitted, calls #update to modify the database. The #edit request is idempotent, the #update method modifies the database.

But there's no equivalent idempotent/non-idempotent pair for deletion, the framework provides only the non-idempotent #destroy method. One implication of this is that it's impossible to construct truly unobtrusive javascript interfaces: #destroy relies on javascript for its implementation.

The Rails framework would benefit from the addition of a #delete method (and route), whose contract is to generate a form that, when submitted, calls #destroy, along the same lines as the #new/#create and #edit/#update methods.

This is a useful parallelism: it's a natural extension to the other methods already in place, it gives the Rails developer more flexibility in creating interfaces, and it will allow truly unobtrusive JS interfaces that work without any Javascript.


+1 for this.

I always do this manually, every time. It would be better if the generators could generate it automatically, along with the views, and it be included in resources route.


+1 i also do not like that JavaScript is needed to confirm the "delete" action.


Yes, this would be an awesome plugin. Rails has very customizable generators since version 3.0 and you should be able to easily implement this.

@josevalim josevalim closed this

@josevalim: Are you asserting that this should NOT become part of the core Rails distro? Or -- just as beatification is a necessary step towards sainthood -- is a plugin a necessary step towards integration into the language?


I guess he means that it is a feature request and not an issue. I do not know if there is a good place for discussing rails feature requests.


Is this not a good place for feature requests? or should this be posted in rails core newsgroup instead?


I wouldn't consider this a feature, I would consider it to be missing core functionality. I am still at a loss as to why you are required to include the whole of jQuery in order to delete records out of the box, this functionality shouldn't require JavaScript at all in my opinion, see:

The comments further support the need for this kind of functionality.


@nbt: I agree with @josevalim. This shouldn't be included into rails core.
It's a specific need, dependent of some user interfaces. Moreover, it's one which is easily fixable.

resources :post do
  collection do
    get 'remove'

It would be cool as a gem though.


Why is this considered a specific need? I would say that the deletion of records is pretty high on the feature list of most applications and this is simply not possible out of the box with Rails, unless you include the whole of jQuery (or a custom solution) and require that users have JavaScript enabled.

Is progressive enhancement/graceful degradation dead?


The most part of application include the whole jQuery and require that uses have JavaScript enabled. If you don't want to follow this so it is specific needs.


That might be the case but these defaults should be sane. Currently when clicking a delete link without JavaScript enabled, you are taken to the show page for that record, you phisically can't delete a record without JavaScript.

I know most people have JavaScript enabled these days but as it's such a simple fix, why not cater for those users also? As a knock on, this delete action would be useful for listing related records that might be deleted etc. and generally better inform the user of what is about to happen.

I'm not against having the JavaScript prompt, but the 'delete' link should go to the 'delete' page when JavaScript is not enabled or not needed in an app, just as the 'edit' link goes to the 'edit' page and the 'new' link goes to the 'new' page. We then end up with:

  • new -> create (POST)
  • edit -> update (PUT)
  • delete -> destroy (DELETE)



If you do care that your delete page should work even if the user doesn't have Javascript enabled, consider making the delete link as a button instead, as HTTP link can't do a POST request (with _method=delete)

I don't see why we really need this. If you call Rails a "RESTful frameworks", then the correct way to delete a resource is to send DELETE /:resources/:id. Since browsers are stupid, we had to use a form to submit a POST request with _method=delete.

BTW, it's generally a bad idea anyway to allow user to issue a GET request to destroy a resource. If you think you really want the route, just go ahead and create one in your application yourself. If you're using Rails 4, consider using a Routing Concern to do that as well.


I'm not suggesting a 'delete' action that deletes the resource, that would be stupid. The 'delete' action simply shows a confirmation form that posts the the 'destroy' action with '_method=delete', that's all. So 'delete' is to 'destroy' what 'edit' is to 'update'.



Since browsers are stupid,

Actually, browsers are smart: they follow the HTML spec exactly, which says that FORMs can only support GET and POST. Using POST to delete something is just fine according to REST:

This is why it's important to separate "What Rails does" from REST.


Yes. I think with routing concerns you can do this easily, we don't need to add anything to the framework. If you care and want to make your application works without javascript just do it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.