Comments (10)
I provided it above. On my side that code does not work correctly
from mongoose.
import mongoose from 'mongoose';
await mongoose.connect('mongodb://localhost:27017/test?directConnection=true');
const PhotoValidator = {
validator: function(photo) {
console.log('Validation');
return photo.path.startsWith('photos/car/');
},
message: 'invalid'
};
const PhotoSchema = new mongoose.Schema({
path: {
type: String,
required: true,
trim: true,
}
});
const CarSchema = new mongoose.Schema({
photo: {
type: PhotoSchema,
required: true,
validate: PhotoValidator
}
});
const CarModel = mongoose.model('CarModel', CarSchema);
await CarModel.deleteMany({});
const car = new CarModel({ photo: { path: 'photos/car/bla.jpg' } });
await car.save();
console.log('Created');
car.set('photo.path', 'bla/bla/bla');
// car.photo.path = 'bla/bla/bla';
// const photo = car.get('photo'); photo.set('path', 'bla/bla/bla');
await car.save();
console.log('Saved');
// One more
console.log('---------------------------------');
const car2 = new CarModel({ photo: { path: 'bla/bla' } });
try {
await car.save();
console.log('Created');
} catch (error) {
console.log('Validation error occurred');
}
Result:
$ node repro.js
Validation
Created
Saved
---------------------------------
Validation
Validation error occurred
from mongoose.
So, as you can see, in the first case, the creation of a new 'car' occurs without any errors because the path is valid. However, when I attempt to change the path in an existing 'car' to an incorrect one and save it, it also gets saved without any errors...
In the second case, I create a 'car' with an incorrect path, and it doesn't save due to a validation error. The same error is expected to occur in the first case when updating.
from mongoose.
it happens not only with set. I commented out other cases it happens as well:
car.photo.path = 'bla/bla/bla';
also does not work.
Any of these ways cannot work
// car.set('photo.path', 'bla/bla/bla');
car.photo.path = 'bla/bla/bla';
// const photo = car.get('photo'); photo.set('path', 'bla/bla/bla');
car.save();
from mongoose.
but if I add the validate method inside the subdocument (directly to the path
field) it works as expected.
The problem is only when validation is on an entire subdocument field...
from mongoose.
const mongoose = require('mongoose');
const PhotoValidator = {
validator: function(photo) {
console.log('Validation');
return photo.path.startsWith('photos/car/');
},
message: 'invalid'
};
const PhotoSchema = new mongoose.Schema({
path: {
type: String,
required: true,
trim: true,
}
});
const CarSchema = new mongoose.Schema({
photo: {
type: PhotoSchema,
required: true,
validate: PhotoValidator
}
});
const CarModel = mongoose.model('CarModel', CarSchema);
run().then(() => process.exit(0)).catch(e => {
console.log(e);
process.exit(-1);
})
async function run() {
await mongoose.connect('mongodb://localhost:27017');
await mongoose.connection.dropDatabase();
await CarModel.deleteMany({});
const car = new CarModel({ photo: { path: 'photos/car/bla.jpg' } });
await car.save();
console.log('Created');
car.set('photo.path', 'bla/bla/bla');
// car.photo.path = 'bla/bla/bla';
// const photo = car.get('photo'); photo.set('path', 'bla/bla/bla');
await car.save();
console.log('Saved, should not have saved');
// One more
console.log('---------------------------------');
const car2 = new CarModel({ photo: { path: 'bla/bla' } });
try {
await car.save();
console.log('Created');
} catch (error) {
console.log('Validation error occurred');
}
}
from mongoose.
This is expected behavior. When saving an existing document, Mongoose only runs validation on paths that have been changed. That means we don't run validation on subdocument paths if the subdocument wasn't directly modified. So if you were to do car.photo = { path: '/bla/bla' }
or car.set('photo.path', '/bla/bla'); car.markModified('photo');
the validator would run, but if you modify photo.path
directly then Mongoose won't re-run photo
validation.
In general, we recommend putting validators on the paths they're validating. So PhotoValidator
belongs on the path
property, not photo
. Does that make sense?
from mongoose.
is there a way to run "force" validation? to validate all fields?
from mongoose.
Yes, but not as elegant as we would like. You need to markModified()
every path you want to validate, like car.markModified('photo')
. So to validate all paths, you can just markModified()
every path in the schema as follows:
car.schema.eachPath(path => car.markModified(path));
We will add a validateAllPaths
option in our next minor release that will run validation on every path, not just modified paths.
from mongoose.
thank you!
from mongoose.
Related Issues (20)
- There is a bug thats i dont save HOT 1
- .populate() clobbers the return type with { [x: string]: NativeDate; } HOT 5
- Entire $OR clause dropped in findOne query when any of the keys does not exist in the mongoose schema HOT 1
- Follow up to "populated documents get saved as strings"
- $push does not push the new item to an array field on mongoDB HOT 1
- mongoose omits filter query parameters, if they are not in the schema, without an error HOT 3
- Mongoose is throwing Unhandled Quiesce mode error that the Mongo driver doesn't throw HOT 7
- Document.prototype.toObject() should run all getters on fields in subdocuments when getters option is set to true HOT 2
- Is there any way to suppress MongoServerError: Collection SOME COLLECTION already exists. HOT 1
- InferRawDocType not same type return from .lean() HOT 3
- Getters not applied in 3-level nested subdoc with `toObject({ getters: true, virtuals: false })` in 8.5 HOT 3
- New FilterQuery type (from 8.6.0) disallows $expr at the query root (type error) HOT 1
- TypeScript returns an error if you run a query on a subclass field of a model HOT 2
- Support for options argument when creating a single document in Model.create() HOT 3
- Array `addToSet()` and `push()` methods do not work with transaction retries HOT 7
- MaxListenersExceededWarning on connection.useDb calls
- Document set merge doesn't work for multi layer nested documents HOT 3
- Breaking TypeScript Change in updateMany from v8.5.5 to v8.6.0 HOT 4
- Breaking TypeScript Change in find from v8.5.5 to v8.6.0 HOT 7
- _id no longer seems to be recursively included when bundled with webpack HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mongoose.