2015-09-18 3 views
0

Это моя схема:Mongoose не проверки типа: [SimSchema]

tango.schema.js

var mongoose = require('mongoose'); 
var Schema = mongoose.Schema; 

var notEmpty = [function(arr) { 
    return arr.length > 0; 
}, "Can't be empty."]; 

var TangoSchema = new Schema({ 
    title: { type: String, required: true }, 
    sims: { type: [SimSchema], required: true, validate: notEmpty }, 
    statements: { type: [StatementSchema], required: true, validate: notEmpty } 
}); 

var SimSchema = new Schema({ 
    name: { type: String, required: true, maxlength: 5 }, 
    description: { type: String, required: true, maxlength: 140 } 
}); 

var StatementSchema = new Schema({ 
    text: { type: String, required: true }, 
    children: { type: [StatementSchema], required: true, validate: notEmpty }, 
    focus: { type: Boolean, required: true }, 
    childrenHidden: { type: Boolean, required: true }, 
    simId: { type: Number, required: true } 
}); 

exports.TangoSchema = TangoSchema; 
exports.SimSchema = SimSchema; 
exports.StatementSchema = StatementSchema; 

Следующий тест не пройден. Она возвращает вместо этого 200 из 400:

it('Sim has no name', function(done) { 
    delete testTango.sims[0].name; 

    agent 
    .post('/tangos') 
    .send(testTango) 
    .expect(400) 
    .end(function(err, res) { 
     if (err) { 
     return done(err); 
     } 
     var result = JSON.parse(res.text); 
     assert(result.error); 
     assert.equal(result.error, 'Tango validation failed'); 
     done(); 
    }) 
    ; 
}); 

Я ожидал, что так как объект танго, который был послан имеет Sim, который не соответствует SimSchema, он бы не был успешно создать танго. Вместо этого он создает Tango успешно и отправляет обратно 200.

Почему это? Разве type: [SimSchema] не сказал, что «это свойство должно быть массивом объектов, которые соответствуют SimSchema»?

+0

Вы уверены, что ваши данные теста верны и что массив был опустошен? Я фактически не вижу ни одного случая, когда пользовательский валидатор будет вызываться, однако: 1. Обязательный атрибут родительской схемы вызовет ошибку для пустого или не существующего массива. 2. Подтверждение подсхемы будет выполняться, если элементы не совпадают с теми же необходимыми правилами. Я думаю, проблема здесь заключается в том, что вы пытаетесь манипулировать этим как объект JavaScript, когда он на самом деле является мангустским документом. Таким образом, вы не можете удалять вещи из массива, как вы пытаетесь сделать, и «изменений» просто не происходит. –

+0

Я думаю, это может быть из-за того, что мои схемы определены. –

ответ

0

Проблема не в проверке, а в манипуляции с самим объектом. Вы рассматриваете это как объект JavaScript при попытке удалить свойство «name» из ваших данных образца в массиве, но проблема в том, что это не простой объект JavaScript, а структура документа mongoose.

Путаница в том, что документ мангуста пытается «похож» на обычный объект JavaScript, но на самом деле свойства, которые вы пытаетесь манипулировать, на самом деле не являются простыми свойствами. Впоследствии изменение ничего не делает;

С основным кодом для воспроизведения:

var mongoose = require('mongoose'), 
    Schema = mongoose.Schema; 

mongoose.connect('mongodb://localhost/test'); 

var childSchema = new Schema({ 
    name: { type: String, required: true } 
}); 

var parentSchema = new Schema({ 
    name: { type: String, required: true }, 
    children: { type: [childSchema], required: true } 
}); 

var Parent = mongoose.model('Parent', parentSchema); 

var obj = new Parent({ name: "Homer", children: [{ name: "Bart"}] }); 

console.log(obj); 

//obj = obj.toObject(); 
delete obj.children[0].name; 

console.log(obj); 

Что собирается показать, что, несмотря на попытку манипуляции, ничего не изменилось:

{ name: 'Homer', 
    _id: 55fb841ce300c51e0ef842e3, 
    children: [ { name: 'Bart', _id: 55fb841ce300c51e0ef842e4 } ] } 
{ name: 'Homer', 
    _id: 55fb841ce300c51e0ef842e3, 
    children: [ { name: 'Bart', _id: 55fb841ce300c51e0ef842e4 } ] } 

Большого намек комментируемой линии есть , так как вам необходимо сначала перенести его обратно на обычный объект, а затем снова лить в качестве документа для мангуста:

obj = obj.toObject(); 
delete obj.children[0].name; 

console.log(obj); 

obj = new Parent(obj); 

obj.save(function(err) { 
    console.log(err); 
}); 

Добавление в этих строках сделать все различие:

{ name: 'Homer', 
    _id: 55fb85439652ee2c0ec8800e, 
    children: [ { name: 'Bart', _id: 55fb85439652ee2c0ec8800f } ] } 
{ name: 'Homer', 
    _id: 55fb85439652ee2c0ec8800e, 
    children: [ { _id: 55fb85439652ee2c0ec8800f } ] } 
{ [ValidationError: Parent validation failed] 
    message: 'Parent validation failed', 
    name: 'ValidationError', 
    errors: 
    { 'children.0.name': 
     { [ValidatorError: Path `name` is required.] 

Вы также не должны пользовательские валидаторы на этих полях массива. Просто установка required будет генерировать исключение, если оно опущено из объекта или если отправлен только и пустой массив. И, конечно, если содержимое документа массива не соответствует определениям подсхемы, тогда эта проверка также инициируется.

+0

'testTango' - объект JavaScript. Я определяю 'var testTango = ...' в моем 'beforeEach'. Я попробовал 'testTango = testTango.toObject()', но он выбросил ошибку. Хорошая мысль о 'required'. Откуда ты это знаешь; есть ли для этого документация (я смотрел и не видел)? –

Смежные вопросы