18

新しいドキュメントに挿入されるデータを検証しようとしていますが、他の多くのことが必要になる前ではありません。そのため、モデル スキーマに対して配列内のオブジェクトを検証する関数を静的メソッドに追加するつもりでした。

これまでのコードは次のとおりです。

module.exports = Mongoose => {
    const Schema = Mongoose.Schema

    const peopleSchema = new Schema({
        name: {
            type: Schema.Types.String,
            required: true,
            minlength: 3,
            maxlength: 25
        },
        age: Schema.Types.Number
    })

    /**
     * Validate the settings of an array of people
     *
     * @param   {array}     people  Array of people (objects)
     * @return  {boolean}
     */
    peopleSchema.statics.validatePeople = function( people ) {
        return _.every(people, p => {
            /**
             * How can I validate the object `p` against the peopleSchema
             */
        })
    }

    return Mongoose.model( 'People', peopleSchema )
}

だからpeopleSchema.statics.validatePeople私は検証をしようとしているところです。私はマングースの検証ドキュメントを読みましたが、データを保存せずにモデルに対して検証する方法については述べていません。

これは可能ですか?

アップデート

ここでの回答の 1 つは、動作しているように見える適切な検証方法を示していましたが、現在はUnhandled rejection ValidationError.

データを検証するために使用される静的メソッドを次に示します(挿入せずに)

peopleSchema.statics.testValidate = function( person ) {
    return new Promise( ( res, rej ) => {
        const personObj = new this( person )

        // FYI - Wrapping the personObj.validate() in a try/catch does NOT suppress the error
        personObj.validate( err => {
            if ( err ) return rej( err )

            res( 'SUCCESS' )
        } )
    })
}

それから私はそれをテストします:

People.testValidate( { /* Data */ } )
    .then(data => {
        console.log('OK!', data)
    })
    .catch( err => {
        console.error('FAILED:',err)
    })
    .finally(() => Mongoose.connection.close())

スキーマ ルールに従わないデータでテストすると、エラーがスローされます。ご覧のとおり、キャッチしようとしましたが、うまくいかないようです。

PS私は私の約束のためにBluebirdを使用しています

4

3 に答える 3

5

を通じてそれを行う 1 つの方法がありますCustom validators。検証に失敗した場合、ドキュメントを DB に保存できませんでした。

var peopleSchema = new mongoose.Schema({
        name: String,
        age: Number
    });
var People = mongoose.model('People', peopleSchema);

peopleSchema.path('name').validate(function(n) {
    return !!n && n.length >= 3 && n.length < 25;
}, 'Invalid Name');

function savePeople() {
    var p = new People({
        name: 'you',
        age: 3
    });

    p.save(function(err){
        if (err) {
             console.log(err);           
         }
        else
            console.log('save people successfully.');
    });
}

または、validate()定義したのと同じスキーマを使用してそれを行う別の方法。

var p = new People({
    name: 'you',
    age: 3
});

p.validate(function(err) {
    if (err)
        console.log(err);
    else
        console.log('pass validate');
});
于 2016-01-31T03:44:34.050 に答える
0

モデルをまったく必要としない次の関数を作成しました。ドキュメントまたはサブドキュメントのいずれであっても、オブジェクトと Mongoose スキーマを渡すだけです。サブドキュメントも再帰的にチェックされます。

const validateObjectAgainstMongooseSchema = ({checkObject, mongooseSchema, currentPath = "object"} = {}) => {
    const errors = [];

    for (const key of Object.keys(checkObject)) {
        const checkObjectType = Array.isArray(checkObject[key]) ? "array" : typeof checkObject[key];
        const mongooseType = mongooseSchema.path(key).instance.toLowerCase();
        const valid = mongooseType === checkObjectType;

        if (checkObjectType === "object") {
            errors.push(
                ...validateObjectAgainstMongooseSchema({
                    checkObject: checkObject[key],
                    mongooseSchema: mongooseSchema.path(key).schema,
                    currentPath: `${currentPath}.${key}`
                })
            );
        } else if (!valid) {
            errors.push(`${currentPath}.${key} should be of type ${mongooseType} but got ${checkObjectType}`);
        }
    }

    return errors;
};

次のスキーマを使用する場合:


const schema = new mongoose.Schema({
        stringType: {
            type: String
        },
        numberType: {
            type: Number
        },
        dateType: {
            type: Date
        },
        boolType: {
            type: Boolean
        },
        arrayType: {
            type: Array
        },
        schemaType: {
            type: new mongoose.Schema({
                embeddedDate: {
                    type: Date
                },
                embeddedBool: {
                    type: Boolean
                }
            })
        }
    });

以下は空の配列を生成します

const errors = schemaUtils.helpers.validateObjectAgainstMongooseSchema({
            checkObject: {
                stringType: "test",
                numberType: 2,
                dateType: new Date("2020-01-01"),
                boolType: true,
                arrayType: ["test", "it"],
                schemaType: {embeddedDate: new Date("2020-01-02"), embeddedBool: true}
            },
            mongooseSchema: schema
        });

この

const errors = schemaUtils.helpers.validateObjectAgainstMongooseSchema({
            checkObject: {
                stringType: 1,
                numberType: "1",
                dateType: 1,
                boolType: 1,
                arrayType: 1,
                schemaType: {embeddedDate: 1, embeddedBool: 1}
            },
            mongooseSchema: schema
        });

収量:

[
      'object.stringType should be of type string but got number',
      'object.numberType should be of type number but got string',
      'object.dateType should be of type date but got number',
      'object.boolType should be of type boolean but got number',
      'object.arrayType should be of type array but got number',
      'object.schemaType.embeddedDate should be of type date but got number',
      'object.schemaType.embeddedBool should be of type boolean but got number'
    ]
于 2021-09-15T15:53:20.097 に答える