Garret Bever
Garret Bever

Reputation: 21

Mongoose Referenced Schemas and Middleware

Im fairly new to developing with mongoose ( using mean stack ) and Im running into an issue of my mongo/mongoose understanding with my current application. What I'm trying to do is to create a forum style relationship between my schemas.

So a category schema is at the root. Under a category are posts. A post can have comments that belong to it. So what I want to happen when I remove a category is the posts will be removed,( no problem there ), but I also want to clean up the comments that were associated with all of the posts that got removed. The issue Im having is the .pre() in my posts does not seem to be fired when my category .pre() deletes the post.

My Category Schema currently:

var mongoose = require('mongoose');

var CategorySchema = new mongoose.Schema({
    categoryname: String,
    categoryslug: String,
    categorydescription: String,
    views: {type: Number, default: 0},
    created: {type: Date, default: Date.now()},
    posts: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Post' }]
});

CategorySchema.methods.addview = function(cb) {
  this.views += 1;
  this.save(cb);
};

// Middleware Remove all the Posts in the category when deleted
CategorySchema.pre('remove', function(next) {
    this.model('Post').remove( { category: this._id }, next );  
});

mongoose.model('Category', CategorySchema);

Deleting a category does infact delete all the posts in that category. Then my post Schema:

var PostSchema = new mongoose.Schema({
    title: String,
    postcontent: String,
    author: {type: String, default: 'Developer'},
    upvotes: {type: Number, default: 0},
    downvotes: {type: Number, default: 0},
    created: {type: Date, default: Date.now()},
    views: Number,
    active: {type: Boolean, default: true},
    comments: [{type: mongoose.Schema.Types.ObjectId, ref: 'Comment'}],
    category: {type: mongoose.Schema.Types.ObjectId, ref: 'Category'}
});

...

PostSchema.pre('remove', function(next) {
    // Remove all the comments associated with the removed post
    this.model('Comment').remove( { post: this._id }, next )

    // Middleware Remove all the category references to the removed post
    this.model('Category').update({ posts: this._id },
    { $pull: { posts: { $in: [this._id] }} } , next);
});


mongoose.model('Post', PostSchema);

Deleting a post does delete the comments tied to it as expected. But when I delete a Category, and the posts get deleted, the middleware never fires to delete the comments of each post.

Upvotes: 1

Views: 250

Answers (1)

Roshan
Roshan

Reputation: 3592

If you are still interested in the answer;

You are using remove(<query>) in you Category middleware to remove Post. From the mongoose documentation;

Note: There is no query hook for remove(), only for documents. If you set a 'remove' hook, it will be fired when you call myDoc.remove(), not when you call MyModel.remove().

You need to fetch the Post and then call delete on that document for this to work.

Upvotes: 1

Related Questions