validate - ¿Por qué Mongoose no valida en la actualización?
mongoose validation (3)
A partir de Mongoose 4.0 puede ejecutar validadores en update()
y findOneAndUpdate()
utilizando el nuevo indicador runValidators: true
.
Mongoose 4.0 presenta una opción para ejecutar validadores en las llamadas a
update()
yfindOneAndUpdate()
. Si activa esta opción, se ejecutarán validadores para todos los campos que su llamada aupdate()
intente$set
$unset
o$unset
.
Por ejemplo, dado el esquema de OP:
var ClientSchema = new Schema({
name: {type: String, required: true, trim: true}
});
var Client = mongoose.model(''Client'', ClientSchema);
Pasando el indicador en cada actualización
Puedes usar la nueva bandera como esta:
var id = req.params.id;
var client = req.body;
Client.update({_id: id}, client, { runValidators: true }, function(err) {
....
});
Usando la bandera en un gancho pre
Si no desea establecer el indicador cada vez que actualice algo, puede establecer un pre
enganche para findOneAndUpdate()
:
// Pre hook for `findOneAndUpdate`
ClientSchema.pre(''findOneAndUpdate'', function(next) {
this.options.runValidators = true;
next();
});
Luego puede update()
usando los validadores sin pasar el indicador runValidators
cada vez.
Tengo este código
var ClientSchema = new Schema({
name: {type: String, required: true, trim: true}
});
var Client = mongoose.mode(''Client'', ClientSchema);
Usando express, creo un nuevo cliente con este código
var client = new Client(req.body);
client.save(function(err, data) {
....
});
Si dejo el campo de nombre vacío en el formulario, mangosta no permite crear el cliente porque lo configuré como se requiere en el esquema. Además, si dejo espacios antes y después del nombre, mangosta eliminar esos espacios antes de guardar.
Ahora, trato de actualizar un cliente con este código
var id = req.params.id;
var client = req.body;
Client.update({_id: id}, client, function(err) {
....
});
Me permitió cambiar el nombre, pero si lo dejo vacío en el formulario, mangosta no valida y guarda un nombre vacío. Si agrego espacios vacíos antes y después del nombre, guarda el nombre con espacios.
¿Por qué mangosta validar en guardar, pero no en la actualización? Lo estoy haciendo de la manera incorrecta?
mongodb: 2.4.0 mangosta: 3.6.0 expreso: 3.1.0 nodo: 0.10.1
En tu modelo, ej. Archivo Category.js:
const CategorySchema = mongoose.Schema({
category_name : {
type : String,
required : [true, ''Category Name Is Required !''],
trim : true,
maxlength : [30, ''Category Name Is To Long !''],
unique : true,
});
const Category = module.exports = mongoose.model("Category",CategorySchema);
En tu archivo de ruta:
router.put("/",(req,res,next)=>{
Category.findOneAndUpdate(
{_id : req.body.categoryId},
{$set : {category_name : req.body.category_name} },
**{runValidators: true}**, function(err,result) {
if(err){
if(err.code === 11000){
var duplicateValue = err.message.match(/".*"/);
res.status(200).json({"defaultError":duplicateValue[0]+" Is Already Exsist !"});
}else{
res.status(200).json({"error":err.message} || {"defaultError":''Error But Not Understood !''});
}
}else{
console.log("From category.js (Route File) = "+result);
res.status(200).json({"success":"Category Updated Successfully!!"});
}
});
No está haciendo nada mal, la validation
se implementa como middleware interno dentro de Mongoose y el middleware no se ejecuta durante una update
ya que es básicamente una transferencia al controlador nativo.
Si desea que se valide la actualización de su cliente, deberá find
el objeto para actualizar, aplicarle los nuevos valores de propiedad (ver el método de extend
de subrayado) y luego llamar a save
en él.
Actualización de Mongoose 4.0
Como se observó en los comentarios y en la respuesta de victorkohl, Mongoose ahora admite la validación de los campos de los operadores $set
y $unset
cuando se incluye la opción runValidators: true
en la llamada de update
.