Ошибка запроса модели Mongoose (findById) в хуках (до промежуточного программного обеспечения) из-за внешней модели - PullRequest
0 голосов
/ 18 октября 2018

В этом случае у меня есть две модели: протокол и комментарий.Каждая модель имеет промежуточное программное обеспечение («pre» или «remove»), которое вызывает другую модель.Вызов промежуточного программного обеспечения Comment в Comment.js останавливается на Protocol.findById (), потому что Protocol является объектом, а не функцией модели.Вот файл console.log (Protocol) в Comment.js

Protocol : [object Object] Type : object

Когда в Protocol.js удаляется const Comment = require('../models/comment'), тогда промежуточное программное обеспечение Comment.js работает, и протокол внутри него видится консольюкак следует:

Protocol : function model(doc, fields, skipId) {
  model.hooks.execPreSync('createModel', doc);
  if (!(this instanceof model)) {
    return new model(doc, fields, skipId);
  }
  Model.call(this, doc, fields, skipId);
} Type : function

Я не понимаю этого поведения.Более того, наоборот, промежуточное программное обеспечение Protocol.js работает нормально даже при том, что Comment.js имеет const Protocol = require('../models/protocol')

Я обнаружил уловку в другой теме , которая должна быть заменена внутрипромежуточное ПО Protocol.findById() от mongoose.model('Protocol').findById(), но это не объясняет проблему.

Сценарии представлены ниже.Если вам нужна дополнительная информация, пожалуйста, дайте мне знать, и я предоставлю ее.Спасибо

Protocol.js модель и промежуточное ПО

// Dependencies
const mongoose = require('mongoose')

//Models
//<!---- If Comment is not required here then the Comment Middleware works ---->!
const Comment = require('../models/comment')

//Schema
const protocolSchema = mongoose.Schema({
    _id : mongoose.Schema.Types.ObjectId,
    title:  {
        type : String,
        required: true
    },
    comments : [{
        type: mongoose.Schema.Types.ObjectId,
        ref : 'Comment',       
    }]
})

//Middleware Hook Call
protocolSchema.pre('remove', async function() { 
    console.log('Starts Protocol.schema.pre(\'remove\')')

    var toBeDeletedProtocol = this

    await removeComments()

    function removeComments(){
        return new Promise ((resolve, reject) => {
            console.log('Starts removeComments()')
            var deletedComments = []

            Comment.find({protocol : toBeDeletedProtocol._id})
            .exec()
            .then( comments => {
                console.log('comments found: ' + comments)
                return resolve()
            })
            .catch(err => {
                console.log('Removing comment(s) related to the deleted protocol failed in protocol remove Hook')
                return reject(err)
            })
        })
    }
}) 

//Model Export
module.exports = mongoose.model('Protocol', protocolSchema)

Comment.js модель и промежуточное ПО

//Dependencies
const mongoose = require('mongoose')

//Models
const Protocol = require('../models/protocol')

//Schema
const commentSchema =  mongoose.Schema(
    {
        _id : mongoose.Schema.Types.ObjectId,
        content: {
            type: String, 
            required : true
        },
        protocol : {
            type: mongoose.Schema.Types.ObjectId,
            ref : 'Protocol',
            required : true,
        }
    }
)

//Middleware Hook Call
commentSchema.pre('save', async function() {
    console.log('Starts Comment.schema.pre(\'save\')')

    var toBeSavedComment = this

    await updateProtocol()

    function updateProtocol(){
        return new Promise ((resolve, reject) => {
            console.log('Starts updateProtocol()')

            console.log('toBeSavedComment : '+ toBeSavedComment) 
            console.log('Protocol : '+ Protocol, 'Type : ' + typeof Protocol)        
            //<!----- the ERROR occurs here -----!>
            Protocol.findById(toBeSavedComment.protocol)
            //<!----- Protocol is seen an object instead of a model function -----!>
            .exec()
            .then( protocol => {
                console.log('protocol found : ' + protocol)
                return resolve()
            })
            .catch(err => {
                console.log('Error in updateProtocol() in Comment.schema pre \'save\'') 
                console.log(err)
                return reject(err)
            })

        })
    } 

})    
//Export
module.exports = mongoose.model('Comment', commentSchema

)

Package.json

{
  "name": "debug",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node server.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.18.3",
    "express": "^4.16.4",
    "mongoose": "^5.3.2",
    "nodemon": "^1.18.4"
  }
}

1 Ответ

0 голосов
/ 14 мая 2019

Прошло много времени, и я до сих пор не сталкивался с той же проблемой, поэтому у меня до сих пор нет ясного решения.Но теперь я вижу ошибку, которая может привести к этому необъяснимому поведению.Я конкатенировал переменные или объекты в console.log, например:

console.log('toBeSavedComment : '+ toBeSavedComment) 
console.log('Protocol : '+ Protocol, 'Type : ' + typeof Protocol)

Вместо этого используйте запятую ",":

console.log('toBeSavedComment : ', toBeSavedComment) 
console.log('Protocol : ', Protocol, 'Type : ' , typeof Protocol)

Объединение объектов в console.log, например, вВеб-служба Amazone: Elastic Beanstalk предотвращает компиляцию API.

Это не настоящий ответ, но я надеюсь, что это может помочь!

...