Browse files

fixed; no longer using $set on paths to an unexisting field

mongodb was throwing 'LEFT_SUBFIELD only supports Object'
  • Loading branch information...
1 parent 116b5dc commit d6e974316a5762e3f6ef3c7a79518e0a3672f056 @aheckmann aheckmann committed Mar 31, 2011
Showing with 60 additions and 33 deletions.
  1. +57 −32 lib/mongoose/document.js
  2. +3 −1 lib/mongoose/model.js
View
89 lib/mongoose/document.js
@@ -187,44 +187,69 @@ Document.prototype.pre = function (method, fn) {
*/
Document.prototype.set = function (path, val) {
- if (typeof path != 'string'){
- var prefix = val ? val + '.' : '';
- for (var i in path){
- if (!(this.schema.path(prefix + i) instanceof MixedSchema)
- && 'undefined' !== typeof path[i]
- && path[i] !== null
- && path[i].constructor == Object) {
- this.set(path[i], prefix + i);
- } else if ('undefined' !== typeof path[i]) {
- this.set(prefix + i, path[i]);
+ if (typeof path != 'string') {
+
+ var prefix = val
+ ? val + '.'
+ : '';
+
+ var keys = Object.keys(path);
+ var i = keys.length;
+ var key;
+
+ while (i--) {
+ key = keys[i];
+ if (!(this.schema.path(prefix + key) instanceof MixedSchema)
+ && undefined !== path[key]
+ && null !== path[key]
+ && Object == path[key].constructor) {
+ this.set(path[key], prefix + key);
+ } else if (undefined !== path[key]) {
+ this.set(prefix + key, path[key]);
}
}
- } else {
- // TODO: do actual checking to see if the value changed
- var schema = this.schema.path(path)
- , parts = path.split('.')
- , obj = this.doc
- , self = this;
-
- if (this.schema.pathType(path) === 'virtual') {
- schema = this.schema.virtualpath(path);
- schema.applySetters(val, this);
- return this;
+
+ return this;
+ }
+
+ // TODO: do actual checking to see if the value changed
+ var schema = this.schema.path(path)
+ , parts = path.split('.')
+ , obj = this.doc
+ , self = this;
+
+ if (this.schema.pathType(path) === 'virtual') {
+ schema = this.schema.virtualpath(path);
+ schema.applySetters(val, this);
+ return this;
+ }
+
+ // When using the $set operator the path to the field must already exist.
+ // Else mongodb throws: "LEFT_SUBFIELD only supports Object"
+ var markedModified;
+ if (parts.length > 1) {
+ for (var i = 0, len = parts.length - 1; i <= len; ++i) {
+ if (null === this.get(parts[i])) {
+ this.activePaths.modify(parts[i]);
+ markedModified = true;
+ break;
+ }
}
+ }
+ if (!markedModified)
this.activePaths.modify(path);
- if ( (!schema || val === null || val === undefined) ||
- this.try(function(){
- val = schema.applySetters(schema.cast(val, self), self);
- })
- ){
- for (var i = 0, l = parts.length; i < l; i++){
- if (i + 1 == l)
- obj[parts[i]] = val;
- else {
- obj = obj[parts[i]] || (obj[parts[i]] = {});
- }
+ if ( (!schema || null === val || undefined === val) ||
+ this.try(function(){
+ val = schema.applySetters(schema.cast(val, self), self);
+ })
+ ){
+ for (var i = 0, l = parts.length; i < l; i++) {
+ if (i + 1 == l) {
+ obj[parts[i]] = val;
+ } else {
+ obj = obj[parts[i]] || (obj[parts[i]] = {});
}
}
}
View
4 lib/mongoose/model.js
@@ -79,7 +79,9 @@ Model.prototype.save = function (fn) {
options.safe = true;
var dirty = this.activePaths.map('modify', function (path) {
- return { path: path, value: self.getValue(path), schema: self.schema.path(path) };
+ return { path: path
+ , value: self.getValue(path)
+ , schema: self.schema.path(path) };
});
if (this.isNew) {

0 comments on commit d6e9743

Please sign in to comment.