# Delete in cascade

**URL:** <https://community.forestadmin.com/t/delete-in-cascade/602>\
**Category:** Help me!\
**Created:** [July 3, 2020, 3:32pm UTC](https://community.forestadmin.com/t/delete-in-cascade/602 "2020-07-03T15:32:47Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Thomas](https://avatars.discourse-cdn.com/v4/letter/t/e36b37/32.png) [@Thomas](https://community.forestadmin.com/u/Thomas)\
**Post date:** [July 3, 2020, 3:32pm UTC](https://community.forestadmin.com/t/delete-in-cascade/602/1 "2020-07-03T15:32:47Z")

</div>

I am currently having the following (forestadmin + mongodb):

User(s) -\> [Has outfit(s)] -\> Outfit(s) -\> [List of item(s)/product(s)] -\> Product(s)

We will, for the sake of this example, take only the Outfit model and the Product model. Here you can find two documents as a possible example (JSON Format):

```javascript
// Outfit document
{
    "_id" : ObjectId("5eeb712dfa3a7b9028787903"),
    "picture_url" : "https://i.skyrock.net/3911/84063911/pics/3226492571_1_2_q8PvGEGD.jpg",
    "outfit_products_ids" : [ 
        ObjectId("5eeb712dfa3a7b9028787904"), 
        ObjectId("5eeb712dfa3a7b9028787905"), 
        ObjectId("5eeb712dfa3a7b9028787906"), 
        ObjectId("5eeb712dfa3a7b9028787907")
    ]
}

// Outfit Product Document
{
    "_id" : ObjectId("5eeb712dfa3a7b9028787905"),
    "outfit_id" : ObjectId("5eeb712dfa3a7b9028787903"),
    "title" : "Chemise bucheron, rouge/noir, a carreaux",
    "picture_url" : "https://www.projet13.com/9959-big_default/chemise-bucheron-rouge-noir-a-carreaux.jpg",
    "price" : NumberLong(4200),
    "redirect_url" : "https://www.projet13.com/6426-chemise-bucheron-rouge-noir-a-carreaux.html?gclid=Cj0KCQjwoaz3BRDnARIsAF1RfLfOJDZobj5gTT_uscskeyUqWgzZ_L2SJYvE_kMmk4weuzZpe-fc8cQaAr-IEALw_wcB#/10-taille-m/32-couleur-rouge"
}

```

Now, if we look at the forest admin part (model definitions), we have the following:

```javascript
// Outfit Document
// This model was generated by Lumber. However, you remain in control of your models.
// Learn how here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models
const mongoose = require('mongoose');

// This section contains the properties of your model, mapped to your collection's properties.
// Learn more here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models#declaring-a-new-field-in-a-model
const schema = mongoose.Schema({ 
  'picture_url': String,
  'outfit_products_ids': { type: [mongoose.Schema.Types.ObjectId], ref: 'OutfitProductsCollection' },
}, {
  timestamps: false,
});

module.exports = mongoose.model('OutfitsCollection', schema, 'OutfitsCollection');

```

```javascript
// Outfit Product Document
// This model was generated by Lumber. However, you remain in control of your models.
// Learn how here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models
const mongoose = require('mongoose');

// This section contains the properties of your model, mapped to your collection's properties.
// Learn more here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models#declaring-a-new-field-in-a-model
const schema = mongoose.Schema({ 
  'outfit_id': { type: mongoose.Schema.Types.ObjectId, ref: 'OutfitsCollection' },
  'title': String,
  'price': Number,
  'redirect_url': String,
  'picture_url': String,
}, {
  timestamps: false,
});

module.exports = mongoose.model('OutfitProductsCollection', schema, 'OutfitProductsCollection');

```

## Expected behavior

Now that I have my `belongsTo` and `hasMany` setup, I would like the following behavior:

- Removing an outfit leads to remove the related outfit products
- Removing an Outfit Product leads to remove an id ($pull) from the `outfit_products_ids` of the related outfit ($belongsTo -\> outfit\_id)

## Question

Is this feature exist in forestadmin?

Thanks

---

<div class="post-metadata">

**Author:** ![rap2h](https://dub1.discourse-cdn.com/flex013/user_avatar/community.forestadmin.com/rap2h/32/25_2.png) [@rap2h](https://community.forestadmin.com/u/rap2h)\
**Post date:** [July 6, 2020, 12:53pm UTC](https://community.forestadmin.com/t/delete-in-cascade/602/2 "2020-07-06T12:53:36Z")

</div>

Hi @Thomas 👋

Since [forest admin agent](https://github.com/ForestAdmin/forest-express-mongoose) relies on [mongoose](https://mongoosejs.com/), ou could try to use the [mongoose’s pre (or post) `remove` middleware](https://mongoosejs.com/docs/middleware.html#pre) on your models. You could find more info here:

- [Forest Admin documentation](https://docs.forestadmin.com/documentation/reference-guide/models/enrich-your-models#adding-a-hook)
- [https://stackoverflow.com/questions/14348516/cascade-style-delete-in-mongoose](https://stackoverflow.com/questions/14348516/cascade-style-delete-in-mongoose)

One other approach would be to override the delete and delete many routes and add your logic here using classic mongoose queries. See how to override routes middleware in [Forest Admin documentation](https://docs.forestadmin.com/documentation/reference-guide/routes/default-routes#delete-a-record).

Let me know if you find your way in creating your cascade logic, otherwise, I could try to help you creating it!

---

<div class="post-metadata">

**Author:** ![Thomas](https://avatars.discourse-cdn.com/v4/letter/t/e36b37/32.png) [@Thomas](https://community.forestadmin.com/u/Thomas)\
**Post date:** [July 6, 2020, 1:07pm UTC](https://community.forestadmin.com/t/delete-in-cascade/602/3 "2020-07-06T13:07:20Z")

</div>

Hey,

Ok I will look at it and come back to you once i work on it!

thanks,

max

---

<div class="post-metadata">

**Author:** ![Thomas](https://avatars.discourse-cdn.com/v4/letter/t/e36b37/32.png) [@Thomas](https://community.forestadmin.com/u/Thomas)\
**Post date:** [July 6, 2020, 4:26pm UTC](https://community.forestadmin.com/t/delete-in-cascade/602/4 "2020-07-06T16:26:25Z")

</div>

Hey,

I did start to look at it but neither post nor pre seems to be part of schema object:

```javascript
// This model was generated by Lumber. However, you remain in control of your models.
// Learn how here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models
const mongoose = require('mongoose');

// This section contains the properties of your model, mapped to your collection's properties.
// Learn more here: https://docs.forestadmin.com/documentation/v/v6/reference-guide/models/enrich-your-models#declaring-a-new-field-in-a-model
const schema = mongoose.Schema({
    'picture_url': String,
    'outfit_products_ids': {type: [mongoose.Schema.Types.ObjectId], ref: 'OutfitProductsCollection'},
    'user_id': {type: mongoose.Schema.Types.ObjectId, ref: 'CertifiedUsersCollection'},
}, {
    timestamps: false,
});

schema.post('remove', function (doc) {
    console.log("test?" + doc);
});

module.exports = mongoose.model('OutfitsCollection', schema, 'OutfitsCollection');

```

I have no output neither, I will try to override the RecordsRemover route

---

<div class="post-metadata">

**Author:** ![Thomas](https://avatars.discourse-cdn.com/v4/letter/t/e36b37/32.png) [@Thomas](https://community.forestadmin.com/u/Thomas)\
**Post date:** [July 7, 2020, 8:56am UTC](https://community.forestadmin.com/t/delete-in-cascade/602/5 "2020-07-07T08:56:21Z")

</div>

Hi 🙂

I am now trying to extend my route (remove many) but I don’t understand how getIdsFromRequest is getting the ids from the request.

I actually would like to get `outfits_products_ids` array from the removed documents in order to call another route from my current route (from removeMany of the first collection, maybe I could call the removeMany of the second collection?)

Thanks

---

<div class="post-metadata">

**Author:** ![Arnaud\_Moncel](https://dub1.discourse-cdn.com/flex013/user_avatar/community.forestadmin.com/arnaud_moncel/32/24_2.png) [@Arnaud\_Moncel](https://community.forestadmin.com/u/Arnaud_Moncel)\
**Post date:** [July 7, 2020, 10:14am UTC](https://community.forestadmin.com/t/delete-in-cascade/602/6 "2020-07-07T10:14:22Z")

</div>

Hi @Thomas 👋 if I understand correctly you try to remove one or many `collection` and all the `products` associated on each collection right ?  
If the post or pre hook doesn’t work you need to be careful :  
This route is called up when you select more than one record.

```javascript
router.delete('/collections'

```

And this one is called if you select `only` one record

```javascript
router.delete('/collections/:recordId'

```

In case of many record selected, you should call

```javascript
new RecordsGetter(collections).getIdsFromRequest(request)
    .then((ids) => {
      // ids here are the ids of all the collection selected(the ones you want to delete)
    }

```

You can after that remove all `product` associated to each collection

```javascript
products.deleteMany({ collection_id: { $in: ids }});

```

And finally remove all the `collections`.

Don’t forget to adapt the behavior on the single delete route.

Let me know if it help.
