diff --git a/lib/include.js b/lib/include.js index 689ab923..4985ff2a 100644 --- a/lib/include.js +++ b/lib/include.js @@ -1,3 +1,7 @@ +var utils = require('./utils'); +var isPlainObject = utils.isPlainObject; +var defineCachedRelations = utils.defineCachedRelations; + /** * Include mixin for ./model.js */ @@ -6,16 +10,6 @@ module.exports = Inclusion; function Inclusion() { } -/*! - * Check if the argument is plain object - * @param {*) include The include value - * @returns {boolean} - */ -function isObject(include) { - return (typeof include === 'object') && (include !== null) - && (include.constructor.name === 'Object'); -} - /** * Allows you to load relations of several objects and optimize numbers of requests. * @@ -40,7 +34,7 @@ Inclusion.include = function (objects, include, cb) { if ( !include || (Array.isArray(include) && include.length === 0) || - (isObject(include) && Object.keys(include).length === 0) + (isPlainObject(include) && Object.keys(include).length === 0) ) { cb(null, objects); return; @@ -58,7 +52,7 @@ Inclusion.include = function (objects, include, cb) { nbCallbacks++; callback(function () { nbCallbacks--; - if (nbCallbacks == 0) { + if (nbCallbacks === 0) { cb(null, objects); } }); @@ -71,7 +65,7 @@ Inclusion.include = function (objects, include, cb) { if (typeof ij === 'string') { ij = [ij]; } - if (isObject(ij)) { + if (isPlainObject(ij)) { var newIj = []; for (var key in ij) { var obj = {}; @@ -87,7 +81,7 @@ Inclusion.include = function (objects, include, cb) { var relations = self.relations; var relationName, subInclude; - if (isObject(include)) { + if (isPlainObject(include)) { relationName = Object.keys(include)[0]; subInclude = include[relationName]; } else { @@ -100,7 +94,7 @@ Inclusion.include = function (objects, include, cb) { return function () { cb(new Error('Relation "' + relationName + '" is not defined for ' + self.modelName + ' model')); - } + }; } var req = {'where': {}}; @@ -138,9 +132,7 @@ Inclusion.include = function (objects, include, cb) { delete keysToBeProcessed[objsIncluded[i][relation.keyTo]]; objectsFrom = objsByKeys[relation.keyFrom][objsIncluded[i][relation.keyTo]]; for (j = 0; j < objectsFrom.length; j++) { - if (!objectsFrom[j].__cachedRelations) { - objectsFrom[j].__cachedRelations = {}; - } + defineCachedRelations(objectsFrom[j]); if (relation.multiple) { if (!objectsFrom[j].__cachedRelations[relationName]) { objectsFrom[j].__cachedRelations[relationName] = []; @@ -156,9 +148,7 @@ Inclusion.include = function (objects, include, cb) { for (var key in keysToBeProcessed) { objectsFrom = objsByKeys[relation.keyFrom][key]; for (j = 0; j < objectsFrom.length; j++) { - if (!objectsFrom[j].__cachedRelations) { - objectsFrom[j].__cachedRelations = {}; - } + defineCachedRelations(objectsFrom[j]); objectsFrom[j].__cachedRelations[relationName] = relation.multiple ? [] : null; } diff --git a/lib/model.js b/lib/model.js index 58211b14..dbc23d5f 100644 --- a/lib/model.js +++ b/lib/model.js @@ -76,8 +76,8 @@ ModelBaseClass.prototype._initProperties = function (data, applySetters) { value: {} }); - if (data['__cachedRelations']) { - this.__cachedRelations = data['__cachedRelations']; + if (data.__cachedRelations) { + this.__cachedRelations = data.__cachedRelations; } // Check if the strict option is set to false for the model diff --git a/lib/scope.js b/lib/scope.js index d37d97c5..a54aad37 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -1,3 +1,5 @@ +var utils = require('./utils'); +var defineCachedRelations = utils.defineCachedRelations; /** * Module exports */ @@ -54,14 +56,12 @@ function defineScope(cls, targetClass, name, params, methods) { throw new Error('Method can be only called with one or two arguments'); } - if (!this.__cachedRelations || (typeof this.__cachedRelations[name] == 'undefined') || actualRefresh) { + if (!this.__cachedRelations || (this.__cachedRelations[name] === undefined) || actualRefresh) { var self = this; var params = mergeParams(actualCond, caller._scope); return targetClass.find(params, function (err, data) { if (!err && saveOnCache) { - if (!self.__cachedRelations) { - self.__cachedRelations = {}; - } + defineCachedRelations(self); self.__cachedRelations[name] = data; } cb(err, data); diff --git a/lib/utils.js b/lib/utils.js index 08804dda..520cf462 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -4,6 +4,8 @@ exports.selectFields = selectFields; exports.removeUndefined = removeUndefined; exports.parseSettings = parseSettings; exports.mergeSettings = mergeSettings; +exports.isPlainObject = isPlainObject; +exports.defineCachedRelations = defineCachedRelations; var traverse = require('traverse'); @@ -176,4 +178,29 @@ function mergeSettings(target, src) { } return dst; +} + +/** + * Define an non-enumerable __cachedRelations property + * @param {Object} obj The obj to receive the __cachedRelations + */ +function defineCachedRelations(obj) { + if (!obj.__cachedRelations) { + Object.defineProperty(obj, '__cachedRelations', { + writable: true, + enumerable: false, + configurable: true, + value: {} + }); + } +} + +/** + * Check if the argument is plain object + * @param {*) obj The obj value + * @returns {boolean} + */ +function isPlainObject(obj) { + return (typeof obj === 'object') && (obj !== null) + && (obj.constructor === Object); } \ No newline at end of file