1

我的数据模型中有两个相似的父子关系树,我正在使用 Mongoose 的中间件来处理级联删除。

第一个层次结构表示如下:

博客层次结构

//blog.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var User = require('./user.js');
var Entry = require('./entry.js');
var Follower = require('./follower.js');

var Blog = new Schema({
    author: {
        type: Schema.Types.ObjectId,
        ref: 'User',
        required: true
    },
    name: {
        type: String,
        required: true
    },
    headerImageUrl: String,
    description:  {
        type: String,
        required: true
    }
}, {
    timestamps: true
});

Blog.pre('remove', function(next) {
    Entry.find({"blogId": this._id})
        .exec(function(err, entries) {
            console.log("found entries " + entries);
            for(var i = entries.length -1; i >= 0; i--) {
                entries[i].remove();
            }
        });
    Follower.remove({"blogId": this._id}).exec();
    next();
});

module.exports = mongoose.model('Blog', Blog);


//entry.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Blog = require('./blog.js');
var Comment = require('./comment.js');

var Entry = new Schema({
    blogId: {
        type: Schema.Types.ObjectId,
        ref: 'Blog'
    },
    title: String,
    thumbnailUrl: String,
    content: String
}, {
    timestamps: true
});

Entry.pre('remove', function(next) {
    Comment.remove({"entryId": this._id}).exec();
    next();
});

module.exports = mongoose.model('Entry', Entry);



//comment.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var User = require('./user.js');
var Entry = require('./entry.js');
var Post = require('./post.js');

var Comment = new Schema({
    text:  {
        type: String,
        required: true
    },
    postedBy:  {
        type: Schema.Types.ObjectId,
        ref: 'User',
        required: true
    },
    parentComment: this,
    entryId: {
        type: Schema.Types.ObjectId,
        ref: 'Entry'
    },
    postId: {
        type: Schema.Types.ObjectId,
        ref: 'Post'
    },
    type: {
        type: String,
        enum: ['BLOG', 'FORUM', 'COMMENT'],
        required: true
    }
}, {
    timestamps: true
});

module.exports = mongoose.model('Comment', Comment);

在这种情况下,当在博客实例上调用 remove 时,该Blog.pre('remove'...功能会执行预期的操作并清除博客实例的所有子级。调用代码如下:

blogRouter.route('/:blogId')

//delete a specific blog by blog id:    [OWNER OR ADMIN USER]
.delete(Verify.verifyOrdinaryUser, Verify.verifyBlogOwnerOrAdmin, function(req, res, next) {
    Blog.findById(req.params.blogId, function(err, blog) {
        if(err) return next(err);
        blog.remove();
        res.json(blog);
    });
});

我对第二个层次结构做同样的事情,在这里直观地表示:论坛层次结构和以下代码:

//forum.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var User = require('./user.js');
var Post = require('./post.js');
var Subscription = require('./subscription.js');

var Forum = new Schema({
    title: {
        type: String,
        required: true
    },
    description: String,
    moderators: [
        {
            type: Schema.Types.ObjectId,
            ref: 'User'
        }
    ]
}, {
    timestamps: true
});

Forum.pre('remove', function(next) {
    Post.find({"forumId": this._id})
        .exec(function(err, posts) {
            console.log("found posts " + posts);
            for(var i = posts.length -1; i >= 0; i--) {
                posts[i].remove();
            }
        });
    Subscription.remove({"forumId": this._id}).exec();
    next();
});

module.exports = mongoose.model('Forum', Forum);


//post.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var User = require('./user.js');
var Forum = require('./forum.js');
var Comment = require('./comment.js');

var Post = new Schema({
    createdBy: {
        type: Schema.Types.ObjectId,
        ref: 'User',
        required: true
    },
    postText: {
        type: String,
        required: true
    },
    forumId: {
        type: Schema.Types.ObjectId,
        ref: 'Forum'
    },
}, {
    timestamps: true
});

Post.pre('remove', function(next) {
    Comment.remove({"postId": this._id}).exec();
    next();
});

module.exports = mongoose.model('Post', Post);


//comment.js [SAME AS INCLUDED ABOVE]

但是在这种情况下,当在论坛实例上调用 remove 时,该Forum.pre('remove'...功能会引发错误:TypeError: Post.find is not a function。错误在 forum.js 第 24 行(Forum.pre(...) 块中的第二行)引发

调用代码如下:

forumRouter.route('/:forumId')

//delete forum by id:  [ADMIN]
.delete(Verify.verifyOrdinaryUser, Verify.verifyAdmin, function(req, res, next) {
    Forum.findById(req.params.forumId, function(err, forum) {
        if(err) return next(err);
        forum.remove();
        res.json(forum);
    });
});

虽然我在这里和其他地方的在线研究中发现了这个错误的实例,但原因是错误导出的模型或错误定义的模式。Post 模式在我的其余代码中成功使用,没有任何问题,只是对 Post.find 的调用导致了错误。事实上,我的 postRouter 代码成功调用了以下代码:

postRouter.route('/')

// retrieve all forum posts:  [ALL USERS]
.get(function(req, res, next) {
    Post.find({})
        .populate({
            path: 'forumId',
            model: 'Forum',
            populate: {
                path: 'moderators',
                model: 'User'
            }
        })
        .populate('createdBy')
        .exec(function(err, posts){
            if(err) return next(err);
            res.json(posts);
        });
});
4

0 回答 0