Ответ 1
Прежде всего, давайте проясним, что валидаторы имеют два типа: валидаторы документов и проверки достоверности обновлений (возможно, вы это уже знаете, но опубликованный вами фрагмент обновляет документ, где в качестве проблемы вы упоминаете подтверждение документа).
Не было никакой разницы. Я получил большой объект (это называется "объектом запроса"?) Это похоже на то, что я читаю здесь.
Проверки документов выполняются при запуске save
в документах, как указано в документах.
Валидация - это промежуточное программное обеспечение. По умолчанию Mongoose регистрирует валидацию как pre ('save') на каждой схеме.
Или вы можете вызвать его вручную с помощью .validate()
Вы можете вручную запустить проверку с помощью doc.validate(callback) или doc.validateSync()
Проверки обновлений проверяются для операций обновления
В приведенных выше примерах вы узнали о проверке документа. 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();
});
Над кодом с триггером проверка обновлений не проверка документа
Чтобы увидеть подтверждение документа в действии uncomment property.save()
и прокомментировать операцию обновления.
Вы заметите, что значением этого будет документ property
.
this { name: 'foo',
occupancy: 'bar',
_id: 598e9d72992907120a99a367,
tenants: [ 1 ] }
Прокомментируйте сохранение, раскомментируйте операцию обновления, и вы увидите большой объект, о котором вы упомянули.
Теперь большой объект, который вы получили, вы, возможно, не осознали, является глобальным объектом, когда вы не установили context: 'query'
и объект запроса при установке контекста.
Это можно объяснить в этой строке в источнике мангуста. Когда контекст не задан, mongoose устанавливает область null
. А затем здесь .call
вызывается с scope
.
Теперь, в нестандартном режиме, когда .call
вызывается с нулевым значением, this
заменяется глобальным объектом. Поэтому проверьте содержимое большого объекта, который у вас есть. Если context
не установлен, это будет глобальный объект, а не объект запроса. Вы можете добавить "use strict";
и увидеть, что null будет зарегистрирован. (Отсканированный фрагмент может подтвердить это для вас). Вы можете проверить, что у вас есть объект запроса, запустив экземпляр mongoose.Query
напротив this
.
Надеюсь, это поможет вам лучше понять ситуацию.