如何使用在 node.js 中有引用的 mongoose 插入 post 方法

How to insert post method with mongoose having a reference in node.js

我正在使用猫鼬并有两个模式模型,其中一个“控制”在第一个模型“框架”模型中有一个参考。 使用 node.js 我试图创建一个 post 方法并在 postman 中测试它,但没有成功。不确定我的处理方式是否正确:

框架架构:

const FrameworkSchema = new Schema({
  name: {
    type: String,
    trim: true
  },
  slug: {
    type: String,
    slug: 'name',
    unique: true
  },
  image: {
    data: Buffer,
    contentType: String
  },
  description: {
    type: String,
    trim: true
  },
  isActive: {
    type: Boolean,
    default: true
  },
  control: 
    {
      type: Schema.Types.ObjectId,
      ref: 'Control'
    },
  updated: Date,
  created: {
    type: Date,
    default: Date.now
  }
});

我的控制架构:

const ControlSchema = new Schema({
   _id: {
     type: Schema.ObjectId,
     auto: true
   },
  mControlNo: {
    type: String
  },
  sControlNo: {
    type: String
  },
  name: {
    type: String,
    trim: true
  },
    slug: {
    type: String,
    slug: 'name',
    unique: true
  },
  description: {
    type: String,
    trim: true
  },
  isApplicable: {
    type: Boolean,
    default: true
  },
  updated: Date,
  created: {
    type: Date,
    default: Date.now
  }
});

我的路由器api:

router.post(
  '/add',
  auth,
  role.checkRole(role.ROLES.Admin),
  async (req, res) => {
    try {
       const name = req.body.name;
       const description = req.body.description;
       const isActive = req.body.isActive;
       const control = {
         mControlNo: req.body.control.mControlNo,
         sControlNo: req.body.control.sControlNo,
         name: req.body.control.name,
         description: req.body.control.description,
         isApplicable: req.body.control.isApplicable
       };

      const framework = new Framework({
        name,
        description,
        isActive,
        control
      });

      const frameworkDoc = await framework.save();

      res.status(200).json({
        success: true,
        message: `Framework has been added successfully!`,
        framework: frameworkDoc
      });
    } catch (error) {
      res.status(400).json({
        error
        // error: 'Your request could not be processed. Please try again.'
      });
    }
  }
);

我在 postman:

中测试时的 json 文档
{
 "name": "NCA2",
 "description": "testdescription",
 "isActive": true,
 "control": 
    {
    "mControlNo": "1",
    "sControlNo": "2",
    "name": "controltest",
    "description": "controldescription",
    "isApplicable": true
    }
}

我得到的响应:

{
    "error": {
        "errors": {
            "control": {
                "stringValue": "\"{\n  mControlNo: '1',\n  sControlNo: '2',\n  name: 'controltest',\n  description: 'controldescription',\n  isApplicable: true\n}\"",
                "kind": "ObjectId",
                "value": {
                    "mControlNo": "1",
                    "sControlNo": "2",
                    "name": "controltest",
                    "description": "controldescription",
                    "isApplicable": true
                },
                "path": "control",
                "reason": {}
            }
        },
        "_message": "Framework validation failed",
        "message": "Framework validation failed: control: Cast to ObjectId failed for value \"{\n  mControlNo: '1',\n  sControlNo: '2',\n  name: 'controltest',\n  description: 'controldescription',\n  isApplicable: true\n}\" at path \"control\""
    }
}

使用像 mongoose 这样的框架的全部意义在于编写模型并让框架检查您发送的 body 是对还是错。您不必将 body 中的每个变量分配给您的模型。您可以简单地编写以下内容,这将节省行数:

const framework = new Framework(req.body);

(当然,假定 body 已通过 body-parser 或其他解析器正确解析为 JSON)。

然后,您检查 descriptionname 是否存在:

if (!description || !name)

但其中 none 存在。 req.body.descriptionreq.body.name 确实存在,可能 framework.descriptionframework.name 也存在,但是 descriptionname 是未定义的变量。

其余代码看起来不错,如果错误仍然存​​在,请按照其他人在评论中的建议打印出 catch 子句中的 error


根据问题中添加的代码和 OP 所做的评论,我们现在有更多要回答的内容。

您有一个 ValidationError 来自 mongoose,这意味着您输入的字段之一不正确。您还可以看到它来自字段 control.

在您的 Framework 架构中,您声明了一个看起来像这样的字段 control

control: 
    {
      type: Schema.Types.ObjectId,
      ref: 'Control'
    },

这意味着 Framework 正在为此字段采用 ObjectID,而不是像您在此处发送的 object:

const framework = new Framework({
        name,
        description,
        isActive,
        control
      });

错误本身是明确的:Mongoose 试图将您的 control object 转换为 ObjectID 当然,它失败了。

您有 2 个解决方案:

  • 要么直接在 Framework 模式中将 Control 模式作为 object 字段实施
  • 或者你在你的路由中单独创建一个Schema object,保存它,并在创建Framework object时将ID给control .

第二种解决方案可能如下所示:

const control = new Control(req.body.control);
const controlDoc = await control.save();
const framework = new Framework({...req.body, control: controlDoc._id});
const frameworkDoc = await framework.save();

第一个看起来像这样:

const FrameworkSchema = new Schema({
  // all your Framework schema
  control: 
    {
      mControlNo: { type: String },
      sControlNo: { type: String },
      name: { type: String, trim: true},
      // and so on....
    },
});