简体   繁体   中英

Mongoose unable to create new document

I have a article model defined as:

var ArticleSchema = new Schema({

    type: String
    ,title: String
    ,content: String

    ,comments: [{
        type: Schema.ObjectId
        ,ref: 'Comment'
    }]

    ,replies: [{
        type: Schema.ObjectId
        ,ref: 'Reply'
    }]


    ,feedbacks: [{
        type: Schema.ObjectId
        ,ref: 'Feedback'
    }]

    ,meta: {
        tags: [String] //anything
        ,apps: [{
            store: String //app store, google play, amazon app store
            ,storeId: String
        }]
        ,category: String
    }


    //normal, deleted, banned
    , status: String
    ,statusMeta: {
        createdBy: {
            type: Schema.ObjectId
            ,ref: 'User'
        }
        ,createdDate: Date
        , updatedBy: {
            type: Schema.ObjectId
            ,ref: 'User'
        }
        ,updatedDate: Date

        ,deletedBy: {
            type: Schema.ObjectId,
            ref: 'User'
        }
        ,deletedDate: Date

        ,undeletedBy: {
            type: Schema.ObjectId,
            ref: 'User'
        }
        ,undeletedDate: Date

        ,bannedBy: {
            type: Schema.ObjectId,
            ref: 'User'
        }
        ,bannedDate: Date
        ,unbannedBy: {
            type: Schema.ObjectId,
            ref: 'User'
        }

        ,unbannedDate: Date
    }
})

I have the following code to create a new article and save it.

var newArticle = new Article()
newArticle.status = helper.constant.articleTypes.other
newArticle.type = req.body.type
newArticle.category = req.body.category
newArticle.title = req.body.title
newArticle.content = req.body.content
newArticle.meta = req.body.meta
newArticle.statusMeta.createdBy = req.user
newArticle.statusMeta.createdDate = new Date
newArticle.save(function(err) {
    if (err)
        return next(err)
}

My pre save hook (helper function)

exports.batchValidationWrapper = function(schema, module, fieldPaths) {
    for (var i = 0; i < fieldPaths.length; i++) {
        var fieldPath = fieldPaths[i]
        ;(function(fieldPath) {
            schema.pre('save', true, function(next, done) {
                var self = this

                var validationFunction = exports.validation[module][fieldPath]
                var msg = validationFunction(self[fieldPath])
                if (msg) {
                    self.invalidate(fieldPath, msg)
                    done(msg)
                }
                else {
                    done()
                }

            })
        })(fieldPath)
    }
}

and in my model i call helper

helper.batchValidationWrapper(ArticleSchema, 'article', [
    'type'
    ,'title'
    ,'content'
    ,'comments'
    ,'replies'
    ,'feedbacks'
    ,'meta.tags'
    ,'meta.apps'
    ,'meta.category'
    ,'status'
    ,'statusMeta.createdBy'
    ,'statusMeta.createdDate'
    ,'statusMeta.deletedBy'
    ,'statusMeta.deletedDate'
    ,'statusMeta.undeletedBy'
    ,'statusMeta.undeletedDate'
    ,'statusMeta.bannedBy'
    ,'statusMeta.bannedDate'
    ,'statusMeta.unbannedBy'
    ,'statusMeta.unbannedDate'


])

helper.validation is defined as following. It's basically bunches of functions that receive input and return error message if any. If no error just return ''

exports.article = {

    type: function(input) {
        if (!input)
            return 'type is requried'
        return passIfAmongTypes('Article', input, constant.articleTypes)
    }

    ,'statusMeta.createdDate': function(input) {
        if (!input)
            return 'created date is required'
        return ''
    }
}

I got error saying that created date is required when I try to create a new article.

I have tried newArticle.markModified('statusMeta') and newArticle.markModified( statusMeta.createdDate ), both not working. I dont think it's necessary to mark it modified, since it's nested object type, not mixed type (from mongoose doc)

I also tried setting newArticle.statusMeta = {} , not working either.

When I set the break point, newArticle.statusMeta.createdDate is undefined

The reason I dont want to use default value for createdDate is that, setting default seems to happen before running pre('save') hook, which makes my validation code always fail

It's my own bug. Inside helper.js I used helper.funcName() instead of exports.funcName() . it's so hard to debug in javascript even with webstorm IDE.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM