After destroying a resource in my Rails application, the user can restore it clicking on a link.
Currently this restore action is routed to the destroy method of the corresponding resource controller.
When this method finds the resource in the database, it destroys it and moves the record in a trash table.
When it does not find the resource in the database, it searches for it in the trash table and if it finds the resource it restores it.
I am not very satisfied by this way of doing, with the destroy method having two purposes: destroy and restore.
I could create a dedicated restore action in my controller, but in a REST way, where would you place the restore request handling? In a dedicated controller? If so, with which method, PUT or POST?
POST is non-idempotent, meaning if you send the same POST request many times, you will get many new items. PUT should be idempotent, since the same update happening on the same resource should have no side effects when executed multiple times.
As for where this action should go, it really depends on your aesthetic sensibilty and how hardcore you want to be about REST versus keeping your Rails controllers clean and well organized.
It’s certainly arguable that a DeletedBob is different resource from a Bob. You could say that a PUT sent to the DeletedBobsController would update the DeletedBob resource, perhaps with a parameter like “deleted=false” to indicate the purpose of the update.
You could also consider Deletions as a resource. Then you could use DELETE on the DeletionsController with the params “resource_type=bob&resource_id=23”. By destroying the deletion, you are restoring the original object. Subsequent identical calls will yield an “object not found” error, as one would expect with DELETE.
Personally, ever since Roy Fielding (original author of the dissertation defining REST) came out and said there’s really nothing wrong with POST, I would consider defining an additional
:put => :restoremethod and route on my BobsController. It keeps the code where another programmer would expect it, and they are likely the only audience for this kind of design.