Mongoose验证属于嵌入式文档

sigwle7e  于 5个月前  发布在  Go
关注(0)|答案(3)|浏览(38)

我有这个问题模式:

// Require Mongoose
import mongoose from "mongoose";
import { rolesSchema } from "./roles.js";
import { storyPointSchema } from "./storyPoint.js";

// Define a schema
const Schema = mongoose.Schema;
/**
 * Issues Report Schema
 */
export const issuesSchema = new Schema({
    team: {
        required: true, 
        type: String,
    },
    teamRoles: {
        type: [rolesSchema],
        required: true
    },
    ticketId: {
        type: String,
        required: true
    },
    issueName: {
        type: String,
        required: true,
    },
    description: {
        type: String,
        required: true
    },
    issueType: {
        type: String,
        enum: ['story', 'bug', 'task', 'sub-task', 'epic'],
        default: 'story',
        required: true
    },
    storyPoints: {
        accepted: storyPointSchema,
        committed: storyPointSchema,
        completed: storyPointSchema,
        estimated: storyPointSchema, 
        actual: storyPointSchema
    }
}, {_id: false})

/**
 * Calculate Full Name
 * Virtual for ticket assignee's full name
 */
issuesSchema.virtual('fullname').get(function () {
    let fullName = ""
    if (this.firstName && this.lastName) {
        fullName = `${this.firstName}, ${this.lastName}`
    }
    return fullName
})

export const Issues =  mongoose.model('Issues', issuesSchema)

字符串
下面是两个嵌入的文档模式:

export const rolesSchema = new Schema({
    firstName: {
        type: String,
        required: true
    },
    lastName:{
        type: String,
        required: true
    },
    role: {
        type:String,
        required: true
    }
})

export const Roles =  mongoose.model('Roles', rolesSchema)

// Require Mongoose
import mongoose from "mongoose";

// Define a schema
const Schema = mongoose.Schema;
/**
 * Story Point Report Schema
 */
export const storyPointSchema = new Schema([{
    storyPoint: {
        type: Number,
        required: true,
        enum: [0,1, 2, 3, 5, 8, 13]
    }
}])


在单元测试中,我可以得到验证器在需要数据丢失或格式错误时抛出的所有错误
以下是验证错误:

{
  "errors": {
    "description": {
      "name": "ValidatorError",
      "message": "Path `description` is required.",
      "properties": {
        "message": "Path `description` is required.",
        "type": "required",
        "path": "description"
      },
      "kind": "required",
      "path": "description"
    },
    "issueName": {
      "name": "ValidatorError",
      "message": "Path `issueName` is required.",
      "properties": {
        "message": "Path `issueName` is required.",
        "type": "required",
        "path": "issueName"
      },
      "kind": "required",
      "path": "issueName"
    },
    "ticketId": {
      "name": "ValidatorError",
      "message": "Path `ticketId` is required.",
      "properties": {
        "message": "Path `ticketId` is required.",
        "type": "required",
        "path": "ticketId"
      },
      "kind": "required",
      "path": "ticketId"
    },
    "team": {
      "name": "ValidatorError",
      "message": "Path `team` is required.",
      "properties": {
        "message": "Path `team` is required.",
        "type": "required",
        "path": "team"
      },
      "kind": "required",
      "path": "team"
    },
    "issueType": {
      "name": "ValidatorError",
      "message": "`foo` is not a valid enum value for path `issueType`.",
      "properties": {
        "message": "`foo` is not a valid enum value for path `issueType`.",
        "type": "enum",
        "enumValues": [
          "story",
          "bug",
          "task",
          "sub-task",
          "epic"
        ],
        "path": "issueType",
        "value": "foo"
      },
      "kind": "enum",
      "path": "issueType",
      "value": "foo"
    }
  },
  "_message": "Issues validation failed",
  "name": "ValidationError",
  "message": "Issues validation failed: description: Path `description` is required., issueName: Path `issueName` is required., ticketId: Path `ticketId` is required., team: Path `team` is required., issueType: `foo` is not a valid enum value for path `issueType`."


您是否发现了这些模式的任何问题,以了解为什么两个嵌入的文档都无法注册与角色或故事点相关的任何错误?

rjee0c15

rjee0c151#

所以我在issueSchema代码中使用这个函数验证了这个问题:

issuesSchema.path('teamRoles').validate(function(teamRoles){
    if(!teamRoles){return false}
    else if(teamRoles.length === 0){return false}
    return true;
}, 'There must be at least one role added to each issue');

字符串
现在你可以看到错误包括在内:

{
  "errors": {
    "description": {
      "name": "ValidatorError",
      "message": "Path `description` is required.",
      "properties": {
        "message": "Path `description` is required.",
        "type": "required",
        "path": "description"
      },
      "kind": "required",
      "path": "description"
    },
    "issueName": {
      "name": "ValidatorError",
      "message": "Path `issueName` is required.",
      "properties": {
        "message": "Path `issueName` is required.",
        "type": "required",
        "path": "issueName"
      },
      "kind": "required",
      "path": "issueName"
    },
    "ticketId": {
      "name": "ValidatorError",
      "message": "Path `ticketId` is required.",
      "properties": {
        "message": "Path `ticketId` is required.",
        "type": "required",
        "path": "ticketId"
      },
      "kind": "required",
      "path": "ticketId"
    },
    "team": {
      "name": "ValidatorError",
      "message": "Path `team` is required.",
      "properties": {
        "message": "Path `team` is required.",
        "type": "required",
        "path": "team"
      },
      "kind": "required",
      "path": "team"
    },
    "teamRoles": {
      "name": "ValidatorError",
      "message": "There must be at least one role added to each issue",
      "properties": {
        "message": "There must be at least one role added to each issue",
        "type": "user defined",
        "path": "teamRoles",
        "value": []
      },
      "kind": "user defined",
      "path": "teamRoles",
      "value": []
    }
  },
  "_message": "Issues validation failed",
  "name": "ValidationError",
  "message": "Issues validation failed: description: Path `description` is required., issueName: Path `issueName` is required., ticketId: Path `ticketId` is required., team: Path `team` is required., teamRoles: There must be at least one role added to each issue"
}

2w2cym1i

2w2cym1i2#

下面是使用保存()生成错误的测试:

import test from 'ava';
import { Issues } from '../../models/issues.js';

test("Validate should throw all validation errors with none of the required issue fields set", async t => {
    const iS = new Issues();
    const except = async () => {
       throw new Error(await iS.save());
    }
    try {
        await except();
    } catch(e) {
        const errors = JSON.stringify(e);
        t.true(errors.includes('`description` is required.'));
        t.true(errors.includes('`issueName` is required.'));
        t.true(errors.includes('`ticketId` is required.'));
        t.true(errors.includes('`team` is required.'));
        t.true(errors.includes("`issueRole` is required. There must be at least one role added to each issue"));
        t.true(errors.includes("`the estimated story point field` is required, either 0, 1, 2, 3, 5, 8, or 13"));
    }
});

字符串

vyswwuz2

vyswwuz23#

为了让默认值或任何验证工作的故事点,我不得不扁平化这个模式(根据Mongoose的文档,它说嵌入的子文档可能是棘手的,因为他们实际上不属于文档,所以验证不会工作。
以下是更新后的storyPointSchema:

// Require Mongoose
import mongoose from "mongoose";
import { ActoValidator } from "../services/validators/ActoValidator.js";
const Validator = new ActoValidator();
   

// Define a schema
const Schema = mongoose.Schema;
/**
 * Story Point Report Schema
 */
export const storyPointSchema = new Schema({
    accepted:{
        type: Number,
        enum: [0,1, 2, 3, 5, 8, 13],
    },
    committed: {
        type: Number,
        enum: [0,1, 2, 3, 5, 8, 13],
    },
    completed: {
        type: Number,
        enum: [0,1, 2, 3, 5, 8, 13],
    },
    estimated: {
        type: Number,
        enum: [0,1, 2, 3, 5, 8, 13],

    },
    actual: {
        type: Number,
        enum: [0,1, 2, 3, 5, 8, 13],
    },  
})

字符串
然后问题模式是:

// Require Mongoose
import mongoose from "mongoose";
import { rolesSchema } from "./roles.js";
import { storyPointSchema } from "./storyPoint.js";

// Define a schema
const Schema = mongoose.Schema;
/**
 * Issues Report Schema
 */
export const issuesSchema = new Schema({
    team: {
        required: true, 
        type: String
    },
    teamRoles: {
        type: [rolesSchema],
        required: true
    },
    ticketId: {
        type: String,
        required: true
    },
    issueName: {
        type: String,
        required: true,
    },
    description: {
        type: String,
        required: true
    },
    issueType: {
        type: String,
        enum: ['story', 'bug', 'task', 'sub-task', 'epic'],
        default: 'story',
        required: true
    },
    storyPoints: {
        type: storyPointSchema,
        required: [true,  "`the estimated story point field` is required, either 0, 1, 2, 3, 5, 8, or 13"],
    }
}, {_id: false})

/**
 * Calculate Full Name
 * Virtual for ticket assignee's full name
 */
issuesSchema.virtual('fullname').get(function () {
    let fullName = ""
    if (this.firstName && this.lastName) {
        fullName = `${this.firstName}, ${this.lastName}`
    }
    return fullName
})
/**
 * Team roles validation for the array items
 */
issuesSchema.path('teamRoles').validate(function(teamRoles){
    if(!teamRoles){return false}
    else if(teamRoles.length === 0){return false}
    return true;
}, '`issueRole` is required. There must be at least one role added to each issue');

export const Issues =  mongoose.model('Issues', issuesSchema)


现在有相应的错误:

{
  "errors": {
    "storyPoints": {
      "name": "ValidatorError",
      "message": "`the estimated story point field` is required, either 0, 1, 2, 3, 5, 8, or 13",
      "properties": {
        "message": "`the estimated story point field` is required, either 0, 1, 2, 3, 5, 8, or 13",
        "type": "required",
        "path": "storyPoints"
      },
      "kind": "required",
      "path": "storyPoints"
    },
    "description": {
      "name": "ValidatorError",
      "message": "Path `description` is required.",
      "properties": {
        "message": "Path `description` is required.",
        "type": "required",
        "path": "description"
      },
      "kind": "required",
      "path": "description"
    },
    "issueName": {
      "name": "ValidatorError",
      "message": "Path `issueName` is required.",
      "properties": {
        "message": "Path `issueName` is required.",
        "type": "required",
        "path": "issueName"
      },
      "kind": "required",
      "path": "issueName"
    },
    "ticketId": {
      "name": "ValidatorError",
      "message": "Path `ticketId` is required.",
      "properties": {
        "message": "Path `ticketId` is required.",
        "type": "required",
        "path": "ticketId"
      },
      "kind": "required",
      "path": "ticketId"
    },
    "team": {
      "name": "ValidatorError",
      "message": "Path `team` is required.",
      "properties": {
        "message": "Path `team` is required.",
        "type": "required",
        "path": "team"
      },
      "kind": "required",
      "path": "team"
    },
    "teamRoles": {
      "name": "ValidatorError",
      "message": "`issueRole` is required. There must be at least one role added to each issue",
      "properties": {
        "message": "`issueRole` is required. There must be at least one role added to each issue",
        "type": "user defined",
        "path": "teamRoles",
        "value": []
      },
      "kind": "user defined",
      "path": "teamRoles",
      "value": []
    }
  },
  "_message": "Issues validation failed",
  "name": "ValidationError",
  "message": "Issues validation failed: storyPoints: `the estimated story point field` is required, either 0, 1, 2, 3, 5, 8, or 13, description: Path `description` is required., issueName: Path `issueName` is required., ticketId: Path `ticketId` is required., team: Path `team` is required., teamRoles: `issueRole` is required. There must be at least one role added to each issue"


我希望这对其他人有帮助:耸耸肩”

相关问题