I changed a number of things to get this to finally work.
I changed the users array to a set-like object because it was a more accurate representation of the data. The keys for the set are the strings for the ObjectId.
To create a new ObjectId, you must have either a 12 byte string or a 24 character hex string. Originally, I tried to do it with a single digit string. I added a spec helper that stores dummy ids with 24 character hex strings.
mongoose.Schema.Types.ObjectId
and mongoose.Types.ObjectId
are two different things. I tried each one before realizing I needed to use both. When creating the Schema, I need mongoose.Schema.Types.ObjectId
. Any other time I'm referring to the type ObjectId, I need mongoose.Types.ObjectId
.
I was trying to return the model from the files where I define them to access them. Instead I needed to call mongoose.model()
to get my models.
With these changes, my model definition now looks like this:
var mongoose = require('mongoose');
var ObjectId = mongoose.Schema.Types.ObjectId;
var ConversationSchema = new mongoose.Schema({
'users': Object,
'messages': [
{
'text': String,
'sender': {'type': ObjectId, 'ref': 'User'}
}
]
});
ConversationSchema.methods.getFriendId = function(userId) {
for (var u in this.users) {
if (u !== userId) return new mongoose.Types.ObjectId(u);
}
return null;
};
// other custom methods...
mongoose.model('Conversation', ConversationSchema);
My test looks like this:
describe('getFriendId()', function(){
var mongoose = require('mongoose');
var ObjectId = mongoose.Types.ObjectId;
require('../../../models/Conversation');
var Conversation = mongoose.model('Conversation');
var helper = require('../spec-helper');
it('should get the friend id', function(){
users = {};
users[helper.ids.user0] = true;
users[helper.ids.user1] = true;
var conversation = new Conversation({ 'users': users });
expect(conversation.getFriendId(helper.ids.user0)).toEqual(new ObjectId(helper.ids.user1));
});
});