typicode / json-server

Get a full fake REST API with zero coding in less than 30 seconds (seriously)
Other
72.05k stars 6.95k forks source link

Incomplete deletion of related data when deleting #1415

Open DylanovE opened 1 year ago

DylanovE commented 1 year ago

Lets say i have a village, inside the village are houses, inside the house are citizens. so a village hasmany > house hasmany > citizen.

When I delete a village in my JSON server, the related houses are correctly deleted, but the citizens related to those houses are for some reason not deleted. This results in incomplete data deletion, which can lead to inconsistency and errors in the data.

Steps to reproduce: Delete a village that has houses that also have citizens in it by using the DELETE method in the API.

Expected result: The village, related houses, and citizens should be deleted by just making a delete request for the village.

Actual result: The village and rhouses are deleted, but the citizens are not deleted and now homeless on a empty field.

what my db.json looks like: `{ "villages": [ { "id": 1, "name": "example name" } ],

"houses": [ { "id": 1, "villageId": 1, "name": "example" } ],

"citizens": [ { "id": 1, "houseId": 1, "name": "example" } ] }`

DylanovE commented 1 year ago

i've tried changing the code for myself but its a puzzle i cant seem to solve hence i made the issue.. it never destroys documents dependant on the dependant documents. this is the destroy code: ` function destroy(req, res, next) { let resource;

if (opts._isFake) {
  resource = db.get(name).value();
} else {
  resource = db.get(name).removeById(req.params.id).value(); // Remove dependents documents

  const removable = db._.getRemovable(db.getState(), opts);

  removable.forEach(item => {
    db.get(item.name).removeById(item.id).value();
  });
}

if (resource) {
  res.locals.data = {};
}

next();

}`

MadhuSaini22 commented 6 months ago

It seems like you're facing an issue where deleting a village doesn't automatically delete related houses and citizens. To achieve this cascading deletion, you may need to implement a custom logic to handle dependent resources.

Here's a modification to your existing code: function destroy(req, res, next) { const villageId = parseInt(req.params.id);

// Remove houses associated with the village db.get("houses").remove({ villageId }).value();

// Remove citizens associated with the houses db.get("citizens").remove((citizen) => { const house = db.get("houses").find({ id: citizen.houseId, villageId }).value(); return house !== undefined; }).value();

// Remove the village itself const removedVillage = db.get("villages").remove({ id: villageId }).value();

if (removedVillage) { res.locals.data = {}; }

next(); }

This modification ensures that when a village is deleted, it first removes associated houses and then removes citizens associated with those houses. Finally, it removes the village itself.

Please adjust the code based on your exact data structure and requirements. It's crucial to handle dependencies in the correct order to avoid inconsistencies.