UNPKG

mongoose

Version:

Mongoose MongoDB ODM

200 lines (165 loc) 4.13 kB
/*! * Module dependencies. */ var Document = require('../document') , inspect = require('util').inspect; /** * EmbeddedDocument constructor. * * @param {Object} obj js object returned from the db * @param {MongooseDocumentArray} parentArr the parent array of this document * @param {Boolean} skipId * @inherits Document * @api private */ function EmbeddedDocument (obj, parentArr, skipId) { if (parentArr) { this.__parentArray = parentArr; this.__parent = parentArr._parent; } else { this.__parentArray = undefined; this.__parent = undefined; } Document.call(this, obj, undefined, skipId); var self = this; this.on('isNew', function (val) { self.isNew = val; }); }; /*! * Inherit from Document */ EmbeddedDocument.prototype.__proto__ = Document.prototype; /** * Marks the embedded doc modified. * * ####Example: * * var doc = blogpost.comments.id(hexstring); * doc.mixed.type = 'changed'; * doc.markModified('mixed.type'); * * @param {String} path the path which changed * @api public */ EmbeddedDocument.prototype.markModified = function (path) { if (!this.__parentArray) return; this._activePaths.modify(path); if (this.isNew) { // Mark the WHOLE parent array as modified // if this is a new document (i.e., we are initializing // a document), this.__parentArray._markModified(); } else this.__parentArray._markModified(this, path); }; /** * Used as a stub for [hooks.js](https://github.com/bnoguchi/hooks-js/tree/31ec571cef0332e21121ee7157e0cf9728572cc3) * * ####NOTE: * * _This is a no-op. Does not actually save the doc to the db._ * * @param {Function} [fn] * @return {EmbeddedDocument} this * @api private */ EmbeddedDocument.prototype.save = function(fn) { if (fn) fn(null); return this; }; /** * Removes the subdocument from its parent array. * * @param {Function} [fn] * @api public */ EmbeddedDocument.prototype.remove = function (fn) { if (!this.__parentArray) return this; var _id; if (!this.willRemove) { _id = this._doc._id; if (!_id) { throw new Error('For your own good, Mongoose does not know ' + 'how to remove an EmbeddedDocument that has no _id'); } this.__parentArray.pull({ _id: _id }); this.willRemove = true; } if (fn) fn(null); return this; }; /** * Override #update method of parent documents. * @api private */ EmbeddedDocument.prototype.update = function () { throw new Error('The #update method is not available on EmbeddedDocuments'); } /** * Helper for console.log * * @api public */ EmbeddedDocument.prototype.inspect = function () { return inspect(this.toObject()); }; /** * Marks a path as invalid, causing validation to fail. * * @param {String} path the field to invalidate * @param {String|Error} err error which states the reason `path` was invalid * @return {Boolean} * @api public */ EmbeddedDocument.prototype.invalidate = function (path, err, first) { if (!this.__parent) return false; var index = this.__parentArray.indexOf(this); var parentPath = this.__parentArray._path; var fullPath = [parentPath, index, path].join('.'); this.__parent.invalidate(fullPath, err); if (first) this._validationError = ownerDocument(this)._validationError; return true; } /** * Returns the top level document of this sub-document. * * @return {Document} */ EmbeddedDocument.prototype.ownerDocument = function () { return ownerDocument(this); } /*! * Returns the top level document of this sub-document. * * @return {Document} */ function ownerDocument (self) { var parent = self.__parent; while (parent.__parent) parent = parent.__parent; return parent; } /** * Returns this sub-documents parent document. * * @api public */ EmbeddedDocument.prototype.parent = function () { return this.__parent; } /** * Returns this sub-documents parent array. * * @api public */ EmbeddedDocument.prototype.parentArray = function () { return this.__parentArray; } /*! * Module exports. */ module.exports = EmbeddedDocument;