# Speeding up :dependent =\> :destroy

**URL:** <https://www.ruby-forum.com/t/speeding-up-dependent-destroy/108131>\
**Category:** Rails\
**Created:** [June 29, 2007, 9:02am UTC](https://www.ruby-forum.com/t/speeding-up-dependent-destroy/108131 "2007-06-29T09:02:43Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![mikel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e480ec/32.png) [@mikel](https://www.ruby-forum.com/u/mikel)\
**Post date:** [June 29, 2007, 9:02am UTC](https://www.ruby-forum.com/t/speeding-up-dependent-destroy/108131/1 "2007-06-29T09:02:43Z")

</div>

I have a tree of models that represent a book. Looks like this:

book  
sections  
documents  
paragraphs  
index entries  
glossary entries  
footnotes  
index entries  
glossary entries

These are all models with has\_many from parent and the child has  
belongs\_to. They also all have dependent =\> :destroy pointing down  
the tree. Delete a section and it nukes everything beneath it.

There is only one problem.

If you select a document, and delete… the AR query is HUGE as it  
searches through and finds each paragraph, which then finds each  
index, glossary, footnote, which then finds each index and glossary.

This takes a LONG time… finding, opening, deleting each record…  
thousands of database queries.

I need a way to speed this up as it is non functional.

Two ways I can see:

Remove the dependent =\> destroy and make a before\_destroy method which  
puts the child delete in a transaction, and then cascade that same  
before\_destroy method in each subclass (feels like a bad hack).

Create a stored procedure in Mysql to handle it (not portable).

Has anyone else fixed this problem before? What is the best way to go  
here?

Regards

Mikel L…

---

<div class="post-metadata">

**Author:** ![mikel](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e480ec/32.png) [@mikel](https://www.ruby-forum.com/u/mikel)\
**Post date:** [June 29, 2007, 5:24pm UTC](https://www.ruby-forum.com/t/speeding-up-dependent-destroy/108131/2 "2007-06-29T17:24:44Z")

</div>

I suggest a different approach.

I have a tree like this and in the after save I update another table  
for containments which i need for some related queries. Then in the  
before\_destroy you can use one join with the containments table to  
delete all enclosed records.

Michael

Here is my after\_save filter for my “Place” class:

# 

# Update all enclosures for records that enclose this record

# 

def update\_containment  
Containment.destroy\_all :contained\_place\_id =\> self.id  
parents = []  
rec = self.parent  
while rec != nil do  
parents \<\< rec.id  
rec = rec.parent  
end  
db = Containment.connection  
db.execute “insert into containments(place\_id,  
contained\_place\_id) values(#{self.id}, #{self.id})”  
for p in parents do  
db.execute "insert into containments(place\_id,  
contained\_place\_id) select #{p}, cont.contained\_place\_id “+  
" from containments as cont where cont.place\_id = #{self.id}”  
end  
end
