Why the Ruby on Rails action "destroy" is not named "delete"?

10,123

Solution 1

Rails uses 4 standard methods(verbs), namely:

  • GET
  • POST
  • PUT
  • DELETE

Besides it has 7 RESTful actions:

  • index
  • new
  • create
  • edit
  • update
  • show
  • destroy

Rails never uses the same verb as the corresponding action. Routing to the action destroy makes it possible to do more than a single DELETE, through the corresponding action in the controller.

This railsguide might be of interest to you: http://guides.rubyonrails.org/routing.html

Explanation

Browsers request pages from Rails by making a request for a URL using a specific HTTP method, such as GET, POST, PUT and DELETE. Each method is a request to perform an operation on the resource. A resource route maps a number of related requests to actions in a single controller.

Now, imagine we have a HTTP GET request, which means you want to read/retrieve data. If the action would have the same name as the verb, GET in this case, it would be overly simplistic. GET can give access to show, index, new or edit actions. They all read data, but the actions themselves are definitely not the same. The same could be said about the DELETE request. This request is processed through the controller and can have different implementations within actions. It might be you want to destroy a post, but it might as well mean you want to log out of your user session. Only having an action called delete would not justify the possibilities related to it, through the controller.

Edit

If you want to know more about how requests from the browser are processed, you could read some information about the M(odel)V(iew)C(ontroller)-model that Rails uses:

http://www.youtube.com/watch?v=3mQjtk2YDkM&noredirect=1

and:

http://betterexplained.com/articles/intermediate-rails-understanding-models-views-and-controllers/

A quote from this link:

The browser makes a request, such as http://mysite.com/video/show/15 The web server (mongrel, WEBrick, etc.) receives the request. It uses routes to find out which controller to use: the default route pattern is “/controller/action/id” as defined in config/routes.rb.

Meaning your initial request will be translated and processed through the webserver and the correct route has to be defined through the controller, where the restful action, such as destroy, is located.

In the early days of Rails, there were only 2 verb's, namely GET and POST (since PUT and DELETE are not supported, which later versions of rails resolved by adding PUT and DELETE through hidden variables. The name of the destroy action never changed, since request and actions are two different things.

Actions || show  || create || update || destroy
SQL     || select|| create || update || delete
REST    || get   || post   || post   || post

Actions || show  || create || update || destroy
SQL     || select|| create || update || delete
REST    || get   || post   || put    || delete

This quote may be of further interest:

"Because the router uses the HTTP verb and URL to match inbound requests, four URLs map to seven different actions."

http://guides.rubyonrails.org/routing.html

Solution 2

For the model part, here is a nice summary from http://www.nickpeters.net/2007/12/21/delete-vs-destroy/:

The delete method essentially deletes a row (or an array of rows) from the database. Destroy on the other hand allows for a few more options. First, it will check any callbacks such as before_delete, or any dependencies that we specify in our model. Next, it will keep the object that just got deleted in memory; this allows us to leave a message saying something like “Order #{order.id} has been deleted.” Lastly, and most importantly, it will also delete any child objects associated with that object!

Knowing that, it only makes sense to call the action in the controller the same as the one in the model. Delete is too simplistic.

Solution 3

Good question.

I feel like it's to encourage you to always use destroy and not delete on your objects.

Actually, delete doesn't trigger any callback.

Solution 4

Here is an very early(2007) answer from Ryan Bates

Basically "delete" sends a query directly to the database to delete the record. In that case Rails doesn't know what attributes are in the record it is deleteing nor if there are any callbacks (such as before_destroy).

The "destroy" method takes the passed id, fetches the model from the database using the "find" method, then calls destroy on that. This means the callbacks are triggered.

You would want to use "delete" if you don't want the callbacks to be triggered or you want better performance. Otherwise (and most of the time) you will want to use "destroy".

source

Share:
10,123
Haralan Dobrev
Author by

Haralan Dobrev

by day: Uber by night: hacking at open-source and new technologies helping communities favourite tech: Git, Vim, VS Code, NodeJS, NestJS, TypeScript, bash interested in: space, EVs, startups, entrepreneurship, politics

Updated on June 05, 2022

Comments

  • Haralan Dobrev
    Haralan Dobrev almost 2 years

    The CRUD principle defines the four basic operations on persistent data:

    • Create,
    • Read,
    • Update,
    • Delete.

    HTTP verbs also use the DELETE word.

    Why does the default routing in Rails use the word "destroy" for the action corresponding to the HTTP verb DELETE?

  • Haralan Dobrev
    Haralan Dobrev about 11 years
    Isn't this about models? I am asking about the actions names in the controllers?
  • apneadiving
    apneadiving about 11 years
    This is the point, I guess the controller action's name is meant to lead you to the proper model's method
  • Haralan Dobrev
    Haralan Dobrev about 11 years
    Could you expand more on this part "Rails never uses the same verb as the corresponding action."? Is there any specific reason for that?
  • Haralan Dobrev
    Haralan Dobrev about 11 years
    1. Why the names of the actions should correspond with the method names of the models? 2. Re: "Delete is too simplistic" - simpler is better. The HTTP verb DELETE is simple, but it is not limited to simple operations. When the action for the HTTP method DELETE is named destroy this only creates more confusion for me.
  • mathieugagne
    mathieugagne about 11 years
    1. Simplistic and simpler are not the same thing. Naming it delete would be "treating complex issues and problems as if they were much simpler than they really are". Destroying a record is sometimes much more than a delete on the sql row. 2. So according to you, we should not name the action update but rather PUT? and rename create to post? HTTP actions and Controller actions are not the same. Post these attributes to that address. Create a new record with these attributes. Simply not the same.
  • Haralan Dobrev
    Haralan Dobrev about 11 years
    But still your whole answer is about the methods in the models. I've actually read the article before asking the question. Why the naming of methods in the ORM should influence the naming in the routes? I would even argue that " erase" is a better name for "destroy" in the ORM. But this is not the problem.
  • Haralan Dobrev
    Haralan Dobrev about 11 years
    Though I may not agree with some decisions made in Rails, this explanation might be the real answer. I would wait a bit before accepting it.
  • mathieugagne
    mathieugagne about 11 years
    I think you're asking a different question here. Keeping in mind the scope of your initial question, it is "destroy" because "delete" would refer to something else. End of the line. Now to "Why the naming of methods in the ORM should influence the naming in the routes?".. I believe you are actually talking about the controller and not the routes since routes' verbs are "match", "get" and "post" (match soon to be out in Rails4). So for controllers my answer would be: why not? It's MVC. Controller talks to Model. Why wouldn't they speak a similar language?
  • Haralan Dobrev
    Haralan Dobrev over 10 years
    This is a good explanation for the delete/destroy difference in the ORM. However I am asking why the action should be named destroy as well (as per the default routes).
  • ahnbizcad
    ahnbizcad about 7 years
    lifecycle and trigger stuff, basically.