2016-06-30 3 views
11

Ошибка учебное упражнение, чтобы получить валидаторы для работы с 'document.update', я наткнулся на то, что я не понимаю.Что делает контекст: опция «запрос» при использовании мангуста?

Я знаю, что это не сработало, но одна из вещей, которые я пробовал, заключалась в настройке моих параметров на {runValidators: true, context: 'query'}. В моей функции проверки достоверности я попробовал console.logging (this), с контекстом и без него: опция «запрос».

Не было никакой разницы. Я получил большой объект (это называется «объектом запроса»?) Это похоже на то, что я читал here.

В приведенной выше функции проверки цвета это означает, что документ проверяется при использовании проверки документа. Однако при запуске проверки обновлений обновляемый документ может не находиться в памяти сервера, поэтому по умолчанию значение этого параметра не определено.

Это не было неопределенным, даже без контекстного варианта.

Я даже попытался сделать его функцией стрелки, чтобы увидеть, было ли в лексике это другое. В этом случае это было undefined, но опять же изменение параметра контекста не помогло. (Я все еще учился, поэтому я не знаю, важна ли эта часть).

в модели:

let Property = mongoose.model('Property', { 
    name: {type:String, required:true}, 
    occupancy: {type:String}, 
    maxTenants: Number, 
    tenants: [{ type:mongoose.Schema.Types.ObjectId, ref: 'Tenant', validate: [checkMaxTenants, "Maximum tenants exceeded for this property. Tenant not added."]}] 
}); 
function checkMaxTenants(val){ 
    console.log("this",this); 
    // return this.tenants.length <= this.maxTenants; 
    return true; 
} 

и в маршруте:

 property.update({$set: {tenants:property.tenants}},{new:true,runValidators:true,context:'query'}, function(err,savedProperty){ 

Что-нибудь помочь мне лучше понять несоответствие между тем, что я думаю, что я читаю и то, что я вижу, было бы здорово !

ответ

3

С самого начала давайте укажем, что валидаторы имеют два типа: валидаторы документов и валидаторы обновлений (возможно, вы уже знаете это, но опубликованный вами фрагмент обновляет документ, где в качестве проблемы, которую вы упоминаете, является проверка документа) ,

Не было никакой разницы. Я получил большой объект (это называется «объектом запроса»?) Это похоже на то, что я читаю здесь.

Валидаторы документов запускаются при запуске save документов, указанных в документах.

Проверка является промежуточным. Mongoose регистрирует валидацию как pre ('save') hook по каждой схеме по умолчанию.

Или вы можете вызвать его вручную с .validate()

Вы можете вручную запустить проверку с помощью doc.validate (обратного вызова) или док.validateSync()

Update валидаторы выполняются для выполнения операций обновления

В приведенных выше примерах, вы узнали о проверке документов. Mongoose также поддерживает проверку для операций update() и findOneAndUpdate().

Это может быть проиллюстрировано следующим фрагментом. Для удобства я изменил тип tenants на простой целочисленный массив, но это должно иметь значение для нашего обсуждения.

// "use strict"; 

const mongoose = require('mongoose'); 
const assert = require('assert'); 
const Schema = mongoose.Schema; 

let Property = mongoose.model('Property', { 
    name: { type: String, required: true }, 
    occupancy: { type:String }, 
    maxTenants: Number, 
    tenants: [ 
    { 
     type: Number, 
     ref: 'Tenant', 
     validate: { 
     validator: checkMaxTenants, 
     message: "Maximum tenants exceeded for this property. Tenant not added." 
     } 
    } 
    ] 
}); 

function checkMaxTenants (val) { 
    console.log("this", this); 
    // return this.tenants.length <= this.maxTenants; 
    return true; 
} 

mongoose.Promise = global.Promise; 
mongoose.createConnection('mongodb://localhost/myapp', { 
    useMongoClient: true, 
}).then(function(db) { 

    const property = new Property({ name: 'foo', occupancy: 'bar', tenants: [1] }); 

    property.update(
    { $set: { tenants: [2, 3] } }, 
    { 
     new: true, 
     runValidators: true, 
     // context: 'query' 
    }, 
    function(err, savedProperty) { 

    } 
) 

    // property.save(); 
}); 

Над кода с триггером валидация обновления не документ проверки

Чтобы увидеть проверки документов в действии раскомментируйте property.save() и комментарии операции обновления.

Вы заметите, что это значение будет property.

this { name: 'foo', 
occupancy: 'bar', 
_id: 598e9d72992907120a99a367, 
tenants: [ 1 ] } 

Прокомментируйте сохранение, раскомментируйте операцию обновления, и вы увидите большой объект, о котором вы упомянули.

Теперь большой объект, который вы получили, возможно, не осознал, является глобальным объектом, если вы не задали context: 'query' и объект запроса при установке контекста.

Это может быть объяснено в this line в источнике мангуста. Когда контекст не был установлен, mongoose задает область действия null. И затем here.call вызывается с scope.

Теперь, в нестандартном режиме, когда .call вызывается с нулевым значением, this is replaced with the global object. Поэтому проверьте содержимое большого объекта, который у вас есть. Когда context не установлен, это будет глобальный объект, а не объект запроса. Вы можете добавить "use strict"; и увидеть, что null будет зарегистрирован. (Отсканированный фрагмент может подтвердить это для вас). Вы можете проверить, что у вас есть объект запроса, запустив instanceof mongoose.Query против this.

Надеюсь, это поможет вам лучше понять ситуацию.

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