mongodb – Mongoose – 填充后更新(Cast Exception)

由于CastERror,我无法更新我的mongoose模式,这样做,但我不知道如何解决它.

旅行架构:

var TripSchema = new Schema({
    name: String,
    _users: [{type: Schema.Types.ObjectId, ref: 'User'}]
});

用户架构:

var UserSchema = new Schema({
    name: String,
    email: String,
});

在我的html页面中,我渲染了一个可以为此行程添加新用户的行程,我通过调用Schema上的findById方法来检索数据:

exports.readById = function (request, result) {
    Trip.findById(request.params.tripId).populate('_users').exec(function (error, trip) {
        if (error) {
            console.log('error getting trips');
        } else {
            console.log('found single trip: ' + trip);
            result.json(trip);
        }
    })
};

这个作品找到了.在我的ui我可以添加新用户到这次旅行,这里是代码:

var user = new UserService();
user.email = $scope.newMail;
user.$save(function(response){   
    trip._users.push(user._id);
    trip.$update(function (response) {
        console.log('OK - user ' + user.email + ' was linked to trip ' + trip.name);

        // call for the updated document in database
        this.readOne();
    })
};

问题在于,当我更新我的Schema时,将填充旅行中的现有用户,意味着存储为旅行中不是id的对象,新用户在旅行中存储为ObjectId.
在更新之前,如何确保填充的用户返回到ObjectId?否则更新将因CastError而失败.

see here for error

最佳答案 我一直在寻找一种优雅的方式来处理这个问题而没有找到一个令人满意的解决方案,或者至少有一个我对使用填充时mongoosejs人们的想法充满自信.尽管如此,这是我采取的路线:

首先,我尝试将保存列表添加到列表中.所以在你的例子中,移动trip._users.push(user._id);超出$save功能.我把这样的动作放在客户端,因为我希望UI在我坚持之前显示更改.

其次,在添加用户时,我继续使用填充的模型 – 也就是说,我不推送(user._id),而是添加完整用户:push(user).这使_users列表保持一致,因为其他用户的id在填充期间已经被相应的对象替换.

所以现在你应该使用一致的填充用户列表.在服务器代码中,在调用$update之前,我将trip._users替换为ObjectIds列表.换句话说,“un-populate”_users:

user_ids = []
for (var i in trip._users){
    /* it might be a good idea to do more validation here if you like, to make
     * sure you don't have any naked userIds in this array already, as you would
     */in your original code.
    user_ids.push(trip._users[i]._id);
}
trip._users = user_ids;
trip.$update(....

当我再次阅读您的示例代码时,看起来您要添加到旅行中的用户可能是新用户?我不确定这是否仅仅是出于问题目的而简化的遗留问题,但如果没有,则需要先保存用户,以便mongo可以在保存行程之前分配ObjectId.

点赞