Allows non-strict mode to accept unknown properties

This commit is contained in:
Raymond Feng 2013-07-24 22:54:47 -07:00
parent 96787ad25f
commit 9b422752a6
2 changed files with 59 additions and 11 deletions

View File

@ -34,12 +34,7 @@ ModelBaseClass.prototype._initProperties = function (data, applySetters) {
var self = this; var self = this;
var ctor = this.constructor; var ctor = this.constructor;
var ds = { var properties = ctor.properties;
properties: ctor.properties,
setters: ctor.settings
};
var properties = ds.properties;
data = data || {}; data = data || {};
Object.defineProperty(this, '__cachedRelations', { Object.defineProperty(this, '__cachedRelations', {
@ -67,18 +62,29 @@ ModelBaseClass.prototype._initProperties = function (data, applySetters) {
this.__cachedRelations = data['__cachedRelations']; this.__cachedRelations = data['__cachedRelations'];
} }
// Check if the strict option is set to false for the model
var strict = ctor.settings.strict;
for (var i in data) { for (var i in data) {
if (i in properties) { if (i in properties) {
this.__data[i] = this.__dataWas[i] = data[i]; this.__data[i] = this.__dataWas[i] = data[i];
} else if (i in ctor.relations) { } else if (i in ctor.relations) {
this.__data[ctor.relations[i].keyFrom] = this.__dataWas[i] = data[i][ctor.relations[i].keyTo]; this.__data[ctor.relations[i].keyFrom] = this.__dataWas[i] = data[i][ctor.relations[i].keyTo];
this.__cachedRelations[i] = data[i]; this.__cachedRelations[i] = data[i];
} else {
if(strict === false) {
this.__data[i] = this.__dataWas[i] = data[i];
} else if(strict === 'throw') {
throw new Error('Unknown property: ' + i);
}
} }
} }
if (applySetters === true) { if (applySetters === true) {
Object.keys(data).forEach(function (attr) { Object.keys(data).forEach(function (attr) {
if((attr in properties) || (attr in ctor.relations) || strict === false) {
self[attr] = data[attr]; self[attr] = data[attr];
}
}); });
} }
@ -170,12 +176,13 @@ ModelBaseClass.prototype.toObject = function (onlySchema) {
var properties = ds.properties; var properties = ds.properties;
var self = this; var self = this;
var schemaless = this.constructor.settings.strict === false || !onlySchema;
this.constructor.forEachProperty(function (attr) { this.constructor.forEachProperty(function (attr) {
if (self[attr] instanceof List) { if (self[attr] instanceof List) {
data[attr] = self[attr].toObject(onlySchema); data[attr] = self[attr].toObject(!schemaless);
} else if (self.__data.hasOwnProperty(attr)) { } else if (self.__data.hasOwnProperty(attr)) {
if(self[attr] !== undefined && self[attr]!== null && self[attr].toObject) { if(self[attr] !== undefined && self[attr]!== null && self[attr].toObject) {
data[attr] = self[attr].toObject(onlySchema); data[attr] = self[attr].toObject(!schemaless);
} else { } else {
data[attr] = self[attr]; data[attr] = self[attr];
} }
@ -184,10 +191,14 @@ ModelBaseClass.prototype.toObject = function (onlySchema) {
} }
}); });
if (!onlySchema) { if (schemaless) {
Object.keys(self).forEach(function (attr) { Object.keys(self).forEach(function (attr) {
if (!data.hasOwnProperty(attr)) { if (!data.hasOwnProperty(attr)) {
data[attr] = this[attr]; if(self[attr] !== undefined && self[attr]!== null && self[attr].toObject) {
data[attr] = self[attr].toObject(!schemaless);
} else {
data[attr] = self[attr];
}
} }
}); });
} }

View File

@ -39,6 +39,43 @@ describe('ModelBuilder define model', function () {
done(null, User); done(null, User);
}); });
it('should not take unknown properties in strict mode', function (done) {
var modelBuilder = new ModelBuilder();
// simplier way to describe model
var User = modelBuilder.define('User', {name: String, bio: String}, {strict: true});
var user = new User({name: 'Joe', age: 20});
// console.log(user);
User.modelName.should.equal('User');
user.should.be.a('object');
// console.log(user);
assert(user.name === 'Joe');
assert(user.age === undefined);
assert(user.toObject().age === undefined);
assert(user.toObject(true).age === undefined);
assert(user.bio === undefined);
done(null, User);
});
it('should be able to define open models', function (done) {
var modelBuilder = new ModelBuilder();
// simplier way to describe model
var User = modelBuilder.define('User', {}, {strict: false});
var user = new User({name: 'Joe', age: 20});
// console.log(user);
User.modelName.should.equal('User');
user.should.be.a('object').and.have.property('name', 'Joe');
user.should.have.property('name', 'Joe');
user.should.have.property('age', 20);
user.should.not.have.property('bio');
done(null, User);
});
it('should be able to define nesting models', function (done) { it('should be able to define nesting models', function (done) {
var modelBuilder = new ModelBuilder(); var modelBuilder = new ModelBuilder();