Skip to content

Instantly share code, notes, and snippets.

@aheckmann
Created April 13, 2012 17:22
Show Gist options
  • Save aheckmann/2378491 to your computer and use it in GitHub Desktop.
Save aheckmann/2378491 to your computer and use it in GitHub Desktop.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var assert = require('assert')
mongoose.connect('localhost', 'testing_findone');
var schema = new Schema({
name: { last: { type: String, required: true} }
});
var A = mongoose.model('A', schema);
mongoose.connection.on('open', function () {
A.findOne({}, ['name'], function (err, doc) {
if (err) console.error(err.stack||err);
assert.equal(null, doc);
console.error('all good');
mongoose.connection.db.dropDatabase(function () {
mongoose.connection.close();
});
});
});
@kof
Copy link

kof commented Apr 13, 2012

Ok, here are steps to reproduce the next issue. The reason I couldn't write a single test in js is because $unset doesn't work for me if trying to delete name.

The issue is, that if quering a not empty document, which doesn't have the subdoc defined in schema, will create an empty object instead. If trying to save it validator will throw error.

  1. run create.js

  2. run this query:

    mongo testing_findone
    db.as.update({}, {$unset: {name: 1}})

  3. run test.js

create.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var assert = require('assert')
mongoose.connect('localhost', 'testing_findone');
var schema = new Schema({
  name: {
    last: {
      type: String,
      required: true
    }
  },
  nick: {
    type: String,
    required: true
  },
  soemthing: String
}, {strict: true});

var A = mongoose.model('A', schema);

mongoose.connection.on('open', function () {
  var a = new A({
    name: {last: 'lastname'},
    nick: 'nick'
  });
  a.save(function(err) {
    assert.equal(null, err);
    console.error('all good');
    mongoose.connection.close();
  });
});

test.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var assert = require('assert')
mongoose.connect('localhost', 'testing_findone');
var schema = new Schema({
  name: {
    last: {
      type: String,
      required: true
    }
  },
  nick: {
    type: String,
    required: true
  },
  soemthing: String
}, {strict: true});

var A = mongoose.model('A', schema);

mongoose.connection.on('open', function () {
  A.findOne({}, function (err, doc) {
    if (err) console.error(err.stack||err);
    console.log(doc);
    doc.save(function(err) {
      assert.equal(null, err);
      console.error('all good');
      mongoose.connection.db.dropDatabase(function () {
        mongoose.connection.close();
      });
    });
  });
});

@kof
Copy link

kof commented Apr 13, 2012

Output

AssertionError: null == {"message":"Validation failed","name":"ValidationError","errors":{"name.last":{"message":"Validator \"required\" failed for path

@kof
Copy link

kof commented Apr 18, 2012

ping

@aheckmann
Copy link
Author

saving a document that is missing a required field is an error. what is the bug?

@kof
Copy link

kof commented Apr 18, 2012

log the document you get with findOne (I have added console.log), the document looks like this on my machine:

{ _id: 4f8f3a2a3144bb0000000001, nick: 'nick', name: {} }

I have removed name property from the database, however findOne returns an empty object .... it is not just missing ....

@aheckmann
Copy link
Author

that is by design. the schema has declared name as an object.

@kof
Copy link

kof commented Apr 18, 2012

ok, didn't know that, then another issue: if you select just the nick property in findOne call, you will still get the same result

A.findOne({}, ['nick'], function (err, doc) {

@kof
Copy link

kof commented Apr 18, 2012

I suppose declared name as an object doesn't consider selected fields and still returns empty objects, which will then cause validation errors while #save ....

@aheckmann
Copy link
Author

A.findOne({}, ['nick'], function (err, doc) { is working on the 2.x and master branch now. I'm still working on some issues for 2.x before releasing.

@kof
Copy link

kof commented Apr 19, 2012

nice, so you could reproduce the issue :)

@kof
Copy link

kof commented Apr 19, 2012

will test it on my huge model with lots of usecases ...

@aheckmann
Copy link
Author

nice!

@kof
Copy link

kof commented May 2, 2012

This is my next issue, custom validation functions are still called on fields which are not selected.

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var assert = require('assert')
mongoose.connect('localhost', 'testing_findone');
var schema = new Schema({
  name: {
    type: String,
    required: true,
    validate: [function(str) {
        return str.length < 20;
    }, 'MaxLength']
  },
  nick: {
    type: String,
    required: true
  },
  soemthing: String
}, {strict: true});

var A = mongoose.model('A', schema);

mongoose.connection.on('open', function () {
  var a = new A({
    name: 'name',
    nick: 'nick'
  });
  a.save(function(err) {
    assert.equal(null, err);

    A.findOne({},['nick'], function (err, doc) {
      if (err) console.error(err.stack||err);
      console.log('"name" in doc should be false but it is - ', 'name' in doc);

      doc.nick = 'blubb';
      doc.save(function(err) {
        console.error(err);
        mongoose.connection.db.dropDatabase(function () {
          mongoose.connection.close();
        });
      });
    });

  });
});

@aheckmann
Copy link
Author

please open a ticket on the repo. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment