Already I have this schema created. Mostly of the time I need that the field v1 must be required, but under extraordinaries conditions the field v1 does not need it. How I do that?
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var MonographSchema = new Schema({
v1: {
type: String,
required: true,
trim: true
},
v3: [
{
_id: false,
_: String,
a: String,
b: String,
c: [String],
t: Number
}
]
});
mongoose.model('Monograph', MonographSchema);
var Monograph = mongoose.model('Monograph');
var monograph1 = new Monograph({
v1: '001ab',
v3: [
{'_': 'BR1.1', 'a': '1.00', 'b': 'T17a', 'c': ['v.1', 'e.2'], 't': '1001'},
{'_': 'BR67.1', 'a': '614.32', 'b': 'T17a', 'c': ['v.2'], 't': '25'},
{'b': 'T17a', 'c': ['v.2'], 't': '25'}
]
});
var monograph2 = new Monograph({
v3: [
{'_': 'BR1.1', 'a': '1.00', 'b': 'T17a', 'c': ['v.1', 'e.2'], 't': '1001'},
{'_': 'BR67.1', 'a': '614.32', 'b': 'T17a', 'c': ['v.2'], 't': '25'},
{'b': 'T17a', 'c': ['v.2'], 't': '25'}
]
});
monograph1.save(); //all fine
monograph2.save(); //I get an error
How I can unset the required: true of v1 on the fly?
Well maybe not "turn off on the fly", but you can just call one of the general .update() forms instead of .save() which does not employ the validation of pre-save hooks:
var async = require('async'),
mongoose = require('mongoose'),
Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/test');
var MonographSchema = new Schema({
v1: {
type: String,
required: true,
trim: true
},
v3: [
{
_id: false,
_: String,
a: String,
b: String,
c: [String],
t: Number
}
]
});
mongoose.model('Monograph', MonographSchema);
var Monograph = mongoose.model('Monograph');
var monograph1 = new Monograph({
v1: '001ab',
v3: [
{'_': 'BR1.1', 'a': '1.00', 'b': 'T17a', 'c': ['v.1', 'e.2'], 't': '1001'},
{'_': 'BR67.1', 'a': '614.32', 'b': 'T17a', 'c': ['v.2'], 't': '25'},
{'b': 'T17a', 'c': ['v.2'], 't': '25'}
]
});
var monograph2 = new Monograph({
v3: [
{'_': 'BR1.1', 'a': '1.00', 'b': 'T17a', 'c': ['v.1', 'e.2'], 't': '1000'},
{'_': 'BR67.1', 'a': '614.32', 'b': 'T17a', 'c': ['v.2'], 't': '25'},
{'b': 'T17a', 'c': ['v.2'], 't': '25'}
]
});
async.series(
[
function(callback) {
Monograph.findByIdAndUpdate(
monograph1._id,
{ "$set": monograph1.toObject() },
{ "upsert": true },
function(err,doc) {
if (err) throw err;
console.log(JSON.stringify( doc, undefined, 2 ));
callback();
}
);
},
function(callback) {
Monograph.findByIdAndUpdate(
monograph2._id,
{ "$set": monograph2.toObject() },
{ "upsert": true },
function(err,doc) {
if (err) throw err;
console.log( JSON.stringify( doc, undefined, 2 ));
callback();
}
);
}
]
);
So both of those calls are going to work without failure:
{
"_id": "542a41389330a912140c20c9",
"v1": "001ab",
"__v": 0,
"v3": [
{
"_": "BR1.1",
"a": "1.00",
"b": "T17a",
"t": 1001,
"c": [
"v.1",
"e.2"
]
},
{
"_": "BR67.1",
"a": "614.32",
"b": "T17a",
"t": 25,
"c": [
"v.2"
]
},
{
"b": "T17a",
"t": 25,
"c": [
"v.2"
]
}
]
}
{
"_id": "542a41389330a912140c20ca",
"__v": 0,
"v3": [
{
"_": "BR1.1",
"a": "1.00",
"b": "T17a",
"t": 1000,
"c": [
"v.1",
"e.2"
]
},
{
"_": "BR67.1",
"a": "614.32",
"b": "T17a",
"t": 25,
"c": [
"v.2"
]
},
{
"b": "T17a",
"t": 25,
"c": [
"v.2"
]
}
]
}
So the "validation" and other methods are in fact "bound" to the .save() method. If you don't use it then the methods don't get called. Oh and you can ask "virtual" fields to be output from .toObject() calls, so there is no need to loose that if you use it.
So either that or just removing the "required" attribute is probably your best approach, but this is possible, just as long as you take more care:
async.series(
[
// Is valid anyway
function(callback) {
monograph1.save(function(err,doc) {
if (err) throw err;
console.log( JSON.stringify( doc, undefined, 2 ) );
callback();
});
},
// Remove the validators and replace
function(callback) {
var hold = monograph2.schema.paths.v1.validators;
monograph2.schema.paths.v1.validators = [];
monograph2.save(function(err,doc) {
if (err) throw err;
console.log( JSON.stringify( doc, undefined, 2 ) );
monograph2.schema.paths.v1.validators = hold;
callback();
});
},
// With validators will fail
function(callback) {
monograph2.save(function(err,doc) {
if (err) throw err;
console.log( JSON.stringify( doc, undefined, 2 ) );
callback();
});
}
]
);
What this shows is that if you remove the "validators" array from the schema path you are using then there will be no check. You could just remove the "required" validator, but for the presented schema that is the only validator present at that path.
Care must be taken as this is a "global" change to the attached schema of the model and until this is replaced then the validator will be considered not to be there. This also means that you are not modifying the "instance" of the object, but the attached object that is used by all instances. So while this is "turned off" is it "off everywhere".
So the real options break down to:
Untimately you can "temporarily" remove this check, but probably not in the way that you might expect and that alone has it's pitfalls.