From 9b422752a69e4b730bec8f723a04a62dfeaeaf93 Mon Sep 17 00:00:00 2001 From: Raymond Feng Date: Wed, 24 Jul 2013 22:54:47 -0700 Subject: [PATCH] Allows non-strict mode to accept unknown properties --- lib/model.js | 33 ++++++++++++++++++++++----------- test/loopback-dl.test.js | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 11 deletions(-) diff --git a/lib/model.js b/lib/model.js index 78a5d9e6..8960032f 100644 --- a/lib/model.js +++ b/lib/model.js @@ -34,12 +34,7 @@ ModelBaseClass.prototype._initProperties = function (data, applySetters) { var self = this; var ctor = this.constructor; - var ds = { - properties: ctor.properties, - setters: ctor.settings - }; - - var properties = ds.properties; + var properties = ctor.properties; data = data || {}; Object.defineProperty(this, '__cachedRelations', { @@ -67,18 +62,29 @@ ModelBaseClass.prototype._initProperties = function (data, applySetters) { 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) { if (i in properties) { this.__data[i] = this.__dataWas[i] = data[i]; } else if (i in ctor.relations) { this.__data[ctor.relations[i].keyFrom] = this.__dataWas[i] = data[i][ctor.relations[i].keyTo]; 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) { Object.keys(data).forEach(function (attr) { - self[attr] = data[attr]; + if((attr in properties) || (attr in ctor.relations) || strict === false) { + self[attr] = data[attr]; + } }); } @@ -170,12 +176,13 @@ ModelBaseClass.prototype.toObject = function (onlySchema) { var properties = ds.properties; var self = this; + var schemaless = this.constructor.settings.strict === false || !onlySchema; this.constructor.forEachProperty(function (attr) { if (self[attr] instanceof List) { - data[attr] = self[attr].toObject(onlySchema); + data[attr] = self[attr].toObject(!schemaless); } else if (self.__data.hasOwnProperty(attr)) { if(self[attr] !== undefined && self[attr]!== null && self[attr].toObject) { - data[attr] = self[attr].toObject(onlySchema); + data[attr] = self[attr].toObject(!schemaless); } else { data[attr] = self[attr]; } @@ -184,10 +191,14 @@ ModelBaseClass.prototype.toObject = function (onlySchema) { } }); - if (!onlySchema) { + if (schemaless) { Object.keys(self).forEach(function (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]; + } } }); } diff --git a/test/loopback-dl.test.js b/test/loopback-dl.test.js index ca8ea8b4..45abf3fb 100644 --- a/test/loopback-dl.test.js +++ b/test/loopback-dl.test.js @@ -39,6 +39,43 @@ describe('ModelBuilder define model', function () { 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) { var modelBuilder = new ModelBuilder();