如何在第一次使用mongoose

时间:2017-11-17 04:14:55

标签: node.js mongoose mongoose-schema

这是一个非常大的架构,但我试图自己处理ObjectId列表的验证,因为我不希望在传递的值是对象时返回错误

var thingSchema = new Schema({

    // origin Id to relate states when new states are created
    thingId: { type: Schema.ObjectId, ref: 'thing' },
    hash: { type: String },

    // organzational properties
    title: { type: String },
    names: { type: [String] },
    realms: { type: [String], default: ["all", "things"] },

    // values
    text: { type: String },
    number: { type: Number },
    url: { type: String },
    json: { type: {} },
    list: { type: [] },
    boolean: { type: Boolean },
    binary: { 
        data: { type: Buffer },
        // binary type .PNG .JPG for decoding if
        extension: { type: String }
    },

    // family relations | inventory of other things | child things | states
    things:     { type: [{ type: Schema.ObjectId, ref: 'thing' }], default: [] },
    parents:    { type: [{ type: Schema.ObjectId, ref: 'thing' }], default: [] },
    states:     { type: [{ type: Schema.ObjectId, ref: 'thing' }], default: [] },
    properties: { type: [{ type: Schema.ObjectId, ref: 'thing' }], default: [] }, // extendable schema support

    // ownership / privacy / access control / billing
    owner: { type: Schema.ObjectId, ref: 'entity' },
    owners: { type: [{ type: Schema.ObjectId, ref: 'entity' }] },
    payees: { type: [{ type: Schema.ObjectId, ref: 'entity' }] },

    // smart contract variable/dynamic pricing
    contract: {
        type: [{
            contractType: { type: String, required: true },
            thing: { type: Schema.ObjectId, ref: 'entity', required: true },
            amount: { type: Number, required: true, default: 1 },
            multiplier: { type: Number, required: true, default: 1 },
            unit: { type: String, required: true }
        }]
    },

    // meta data
    created: { type: Date, default: Date.now() },
    inception: { type: Date, default: Date.now() },
    age: { type: Number, default: 0 },
    lifetime: { type: Number, default: 0, min: 0, max: Infinity },
    location: { type: String },
    valueType: { type: String, enum: [
        String,
        Object,
        Number,
        Array,
        ]
    },

    // state meta data
    stateId: { type: String },
    stateCreated: { type: Date, default: Date.now() },

},{
    usePushEach: true
})

thingSchema.pre('validate', function(next){
    // custom validate passed properties, parents, things, and states to make sure they're not objects
    let validations = ['properties', 'things', 'parents', 'states']
    for(var i=0;i<validations.length;i++){
        for(var j=0;j<this[validations[i]].length;j++){
            console.log(this[validations[i]][j])
            console.log(i)
            console.log(j)
            if(!(this[validations[i]][j] instanceof Schema.ObjectId)){
                this[validations[i]].splice(j, 1)
                j--
            }
        }
    }
    next()
})

var thingModel = node.model('thing', thingSchema)

但是当我跑步时

let thingModelled = new thingModel(JSON.parse(JSON.stringify(thing)))
预钩子没有运行,我无法判断这些预挂钩是否仅在保存功能上运行?

或者如何在模型创作上运行钩子?

这是运行时的错误     new thingModel(数据)

ValidationError: properties: Cast to Array failed for value "[ { title: 'options',
4|agoraser |     list: [ 'editing', 'edited' ],
4|agoraser |     things: [],
4|agoraser |     properties: [] } ]" at path "properties"
4|agoraser |     at new ValidationError (/media/rick/hyper/Dropbox/host-root/var/www/nodes/agora/server/node_modules/mongoose/lib/error/validation.js:28:11)
4|agoraser |     at model.Document.invalidate (/media/rick/hyper/Dropbox/host-root/var/www/nodes/agora/server/node_modules/mongoose/lib/document.js:1658:32)
4|agoraser |     at model.Document.$set (/media/rick/hyper/Dropbox/host-root/var/www/nodes/agora/server/node_modules/mongoose/lib/document.js:760:10)
4|agoraser |     at model._handleIndex (/media/rick/hyper/Dropbox/host-root/var/www/nodes/agora/server/node_modules/mongoose/lib/document.js:590:14)
4|agoraser |     at model.Document.$set (/media/rick/hyper/Dropbox/host-root/var/www/nodes/agora/server/node_modules/mongoose/lib/document.js:550:24)
4|agoraser |     at model.Document (/media/rick/hyper/Dropbox/host-root/var/www/nodes/agora/server/node_modules/mongoose/lib/document.js:77:12)
4|agoraser |     at model.Model (/media/rick/hyper/Dropbox/host-root/var/www/nodes/agora/server/node_modules/mongoose/lib/model.js:55:12)
4|agoraser |     at new model (/media/rick/hyper/Dropbox/host-root/var/www/nodes/agora/server/node_modules/mongoose/lib/model.js:3879:13)

1 个答案:

答案 0 :(得分:0)

要在save之前验证某个字段,您可以使用schemaName.path('fieldName').validate(function(value, done){....},"error message")此签名。此方法称为pre保存,如果违反了验证规则并且save已中止,error将返回到您的callback

例如,如果您要为states创建验证,请遵循此

thingSchema.path('states').validate(function (value, done) {
  // your logic for validation
  // value will contain the value of state field
  if(validate) {
    return done(true);
  } else {
    return done(false);
  }
}, 'Invalid state');