Reputation: 3242
I've got 2 schema's. One user schema, and a project schema. The user schema holds a reference to the project schema. User Schema:
const UserSchema = new Schema({
username: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
projects: [
{
type: Schema.Types.ObjectId,
ref: 'Project'
}
]
});
Project schema:
const projectSchema = new Schema({
experience: [
{
company: String,
positionExperience: String,
descriptionExperience: String,
websiteExperience: String,
timeperiodExperience: Array,
}
],
education: [
{
school: String,
degree: String,
descriptionEducation: String,
websiteEducation: String,
timeperiodEducation: Array
},
],
}, {
collection: 'project'
});
When the currently logged in user saves a project, it gets pushed inside the projects array in the user schema with:
user.projects.push(project);
I got a delete route which lets the user delete projects:
router.delete('/delete/:id', passport.authenticate('jwt', { session: false }), (req, res, next) => {
Project.findByIdAndRemove({ _id: req.params.id }, (err) => {
if (err) res.json(err)
else res.json('Succesfully removed')
});
})
However, the project id's are not removed from the currently logged in user's collection in the database. Log of DB:
"_id" : ObjectId("5d9474c2dccfb181dd8e9fde"),
"projects" : [
ObjectId("5d9474cddccfb181dd8e9fdf"),
ObjectId("5d94753e9b610a81f83937e9"),
ObjectId("5d947602f72f0f820f2974f0"),
ObjectId("5d947ae435d2e982535d9a53"),
],
"username" : "b",
"password" : "$2a$10$4T1TjmFYD/01wEdMbiSRMeKNVKegnkVBOGGHasP.qJjVbQzmgEZDO",
"email" : "b",
All of the projects are deleted but are their id's are still in the users record. I need some kind of garbage collection to remove those aswell. I looked at Cascade Delete. Cascade delete means that if a record in the parent table is deleted, then the corresponding records in the child table will automatically be deleted. In my case the user is the parent table and I'm not trying to delete a user, I'm trying to delete a project associated with the user. I've tried things like this:
User.findOne({ username: req.user.username }, (err, user) => {
Project.remove({
"_id": {
$in: user.projects
}
}, function(err) {
if(err) return next(err);
user.deleteOne()
})
})
But that deletes the whole user... How can I delete both a project from the projects collection and the projects corresponded with the logged in user? Thanks in advance.
* ----- EDIT ----- *
After some more digging, and thanks to the very usefull answers, this is what I came up with:
//delete route
router.delete('/delete/:id', passport.authenticate('jwt', { session: false }), (req, res, next) => {
User.findOneAndUpdate({ username: req.user.username }, {
$pull: {
'projects': req.params.id
}
}, function (err, model) {
if (!err) {
Project.findByIdAndRemove({ _id: req.params.id }, (err) => {
if (err) res.json(err)
else res.json('Succesfully removed')
});
}
else {
res.status(500).json(err)
}
});
})
Upvotes: 4
Views: 4083
Reputation: 2045
User.findOneAndUpdate({ username: req.user.username }, { $set : { projects : []
} }, (err, user) => {
Project.remove({
"_id": {
$in: user.projects
}
}, function(err) {
if(err) return next(err);
user.deleteOne()
})
})
This will do the trick and findOneAndUpdate will return the original document instead of the updated one.
Upvotes: 0
Reputation: 181
You would need to write your own remove function. Have a look at this question where this problem is already handled.
Upvotes: 2