首页 > 解决方案 > 数据库中保存模型的错误(MongoDB)

问题描述

一般情况下,按照方案创建数据库的时候,控制台会弹出一个错误,就是我没有在数据库中正确写入东西。如何解决这个问题?电路本身:

let mongoose = require(`mongoose`);
let Schema = mongoose.Schema;


let newOrder = new Schema({
    courses: [
      {
        course: {
          type: Object,
          required: true
        },
        Count: {
          type: Number,
          required: true
        }
      }
    ],
    user: {
      name: String,
      userId: {
        type: Schema.Types.ObjectId,
        ref: `user`,
        required: true
      }
    },
    date: {
      type: Date,
      default: Date.now
    }
})


module.exports = mongoose.model(`order`, newOrder);

用户架构:

    let mongoose = require(`mongoose`);
let Schema = mongoose.Schema;

let NewUser = new Schema({
    email: {
        type: String,
        required: true 
    },
    name: {
        type: String,
        required: true
    },
    cart: {
        items: [
            {
                Count: {
                    type: Number,
                    required: true,
                    default: 1
                },
                CourseId: {
                    type: Schema.Types.ObjectId,
                    ref: `products`,
                    required: true
                }
            }
        ]
    }
})


// Метод для добавления или увеличения количества продуктов в корзине
NewUser.methods.addToBasket = function (prod){
    let clone = [...this.cart.items];
    
    let idx = clone.findIndex((event)=>{
         return event.CourseId.toString() === prod._id.toString();
    })

    if(idx > -1){
        clone[idx].Count = clone[idx].Count + 1;
    } else {
        clone.push({
            Count: 1,
            CourseId: prod._id
        })
    }

    // Устанавливаем обновленный массив продуктов в корзине пользователя
    this.cart = {items: clone};
    return  this.save();

}

// Метод для удаления или уменьшения количества продуктов в корзине
NewUser.methods.remToBasket = function (id){
    let clone = [...this.cart.items];

    let idx = clone.findIndex((event)=>{
        return event.CourseId.toString() == id.toString();
    });

    if(clone[idx].Count === 1){
        // Фильтром мы перебираем все елементы в нашей 
        // корзине и перезаписываем елементы опять в эту же 
        // корзину только если перебираемый id не равен 
        // id который мы отослали на сервер удалить
        clone = clone.filter((event)=>{

           return event.CourseId.toString() !== id.toString();

        })
        console.log(clone);
    } else { 
        clone[idx].Count--;
    }

    this.cart = {items: clone};
    this.save();
}

NewUser.methods.clearProd = function (){
    this.cart = {items: []}
    return this.save();
}


mongoose.model(`user`, NewUser);

这是我在路由器中创建它的方法:

let {Router} = require(`express`);
let Order = require(`../models/or`);
let router = Router();

// Обычьный get запрос для получения страницы
router.get(`/`, function(req, res){
  res.render(`order.hbs`, {
    order: true
  })
})

// Post запрос присылающий в базу данных заказ пользователя
router.post(`/`, async (req,res)=>{
  let user = await req.user.cart.populate(`cart.items.CourseId`).execPopulate();
     

  let order = new Order({
    user: {
      name: req.user.name,
      userId: req.user
    },
    courses: user
  })


  await order.save();
  await req.user.clearProd();
  
  res.redirect(`/order`);
})


module.exports = router;

但是基础不是用这样的方案创建的,会弹出一个错误:

(节点:8860)UnhandledPromiseRejectionWarning:ValidationError:订单验证失败:courses.0.Count:Count需要路径。,courses.0.course:路径course是必须的。在 Model.Document.invalidate (C:\Users\Хорошо\Desktop\Node.js\node_modules\mongoose\lib\document.js:2729:32) 在 EmbeddedDocument.invalidate (C:\Users\Хорошо\Desktop\Node. js\node_modules\mongoose\lib\types\embedded.js:298:29) 在 C:\Users\Хорошо\Desktop\Node.js\node_modules\mongoose\lib\document.js:2541:17 在 C:\Users \Хорошо\Desktop\Node.js\node_modules\mongoose\lib\schematype.js:1255:9 在 processTicksAndRejections (internal/process/task_queues.js:79:11) (node:8860) UnhandledPromiseRejectionWarning: 未处理的承诺拒绝。此错误源于在没有 catch 块的情况下抛出异步函数内部,或拒绝未使用 .catch() 处理的承诺。要在未处理的 Promise 拒绝时终止节点进程,请使用 CLI 标志--unhandled-rejections=strict(请参阅https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode)。(拒绝 id:1)(节点:8860)[DEP0018] DeprecationWarning:不推荐使用未处理的承诺拒绝。将来,未处理的 Promise 拒绝将使用非零退出代码终止 Node.js 进程。

标签: javascriptnode.jsmongodb

解决方案


错误消息表明,该user变量不包含所需的属性courses。您尚未显示req.user.cart.populate(cart.items.CourseId).execPopulate()返回的内容,但错误表明返回的值不包含Count. 也许你写count的是小写的c?或者可能根本没有归还财产。如果您不确定,请附加调试器或打印user到控制台 ( )。console.log(user)

let user = await req.user.cart.populate(`cart.items.CourseId`).execPopulate();

let order = new Order({
  user: {
    name: req.user.name,
    userId: req.user
  },
  //       ↓ Make sure the the object you pass here actually contains "Count"
  courses: user
})

您的架构要求课程是具有 acourseCount属性的对象数组。错误说不user包含Count.

courses: [
  {
    course: {
      type: Object,
      required: true
    },
    Count: {
      type: Number,
      required: true
    }
  }
]

附带说明: express 不处理async函数。这意味着不会处理任何抛出的错误(如您的示例)。这就是导致长错误消息和警告的原因。要正确捕获和处理路由处理程序中的错误,您可以使用类似的包express-promise-router(免责声明:我维护此包)。它将Routerfrom express 替换为正确捕获和处理错误的方法。


推荐阅读