simo
simo

Reputation: 24558

destroy vs destroy_all

I need to know when to use :dependent => :destroy_all and when to use :dependent => :destroy

What happen if my model has_many child models, and I used :dependent => :destroy ? will it destroy only the first child model ?

is this line of code wrong:

has_many books, :dependent => :destroy

shall it be like this:

has_many books, :dependent => :destroy_all

?

Upvotes: 6

Views: 9705

Answers (2)

Jorge Gajon
Jorge Gajon

Reputation: 1769

This will destroy all books associated with the model:

has_many books, :dependent => :destroy

An important thing to remember is that :dependent => :destroy will cause the calling of the #destroy method in each and every one of the associated Books. By calling #destroy on each Book, any before_destroy or after_destroy callback will be executed for each Book.

Naturally, if you have a LOT of dependent books, this process could be expensive.

The :destroy_all is invalid, maybe you were thinking about :delete_all. The difference with :delete_all (instead of just :destroy) is that Rails will issue a single SQL statement to delete all dependent book records. No #destroy method will be called on any Book record, and no before_destroy or after_destroy callback will be executed.

The upside is that a single SQL statement is many times more efficient to delete records from the database than calling #destroy on each one of them.

This is very important to know. If you have any *_destroy callbacks on the Book model, you should be aware that defining :dependent => :delete_all will have the effect of ignoring any callbacks you defined on the Book model.

Upvotes: 7

Geoff
Geoff

Reputation: 2228

I'm pretty sure the first line is correct and the second line is incorrect.

Here's a link to the specific section in the documentation:

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many-label-Options

My understanding is that :dependent will loop through the associations and call the given function which means :destroy is the correct one to call. (:destroy_all is only valid for collections.)

I hope that helps.

Upvotes: 0

Related Questions