Should deleting a non-existent resource result in a 404 in RESTful Rails?

Brad picture Brad · Jun 25, 2011 · Viewed 11.2k times · Source

In a brand new Rails application with a scaffolded RESTful model, the generated delete code looks like this:

class BeersController < ApplicationController
  # DELETE /beers/1
  # DELETE /beers/1.xml
  def destroy
    @beer = Beer.find(params[:id])
    @beer.destroy

    respond_to do |format|
      format.html { redirect_to(beers_url) }
      format.xml  { head :ok }
    end
  end
end

If a user tries to delete the same Beer twice (maybe a quick double-click, or actions in two different browser tabs) they will get a RecordNotFound error resulting in a 404 page. This is a pretty unfriendly experience; it seems like it would be better to complete the redirect back to beers_url regardless, possibly with a flash error, since there isn't really anything the user can do about the second delete failing.

An alternative approach is to act like the delete succeeded anyway with something like this:

def destroy
  @beer = Beer.find_by_id(params[:id])
  destroyed = @beer.try(:destroy)        

  respond_to do |format|
    format.html { redirect_to(beers_url) }
    format.xml  { destroyed ? head(:ok) : head(:not_found) }
  end
end

I can understand the desire for a hard 404 error in the API use-case, but it's harder for me to justify for a web application. Can anyone provide a good reason why we should throw a scary error at the user in the name of RESTfulness?

(This question isn't particular to Rails, but I don't know how other frameworks handle this case out of the box).

Answer

Gili picture Gili · May 19, 2013

UPDATE: It turns out I was wrong: https://stackoverflow.com/a/24713946/14731


Previous answer: HTTP DELETE is an idempotent operation. Invoking it multiple times consecutively must result in the same behavior as the first. Meaning: you shouldn't return HTTP 404.