错误:ValidationError:CastError:对于值,转换为ObjectID失败

时间:2017-05-21 14:15:24

标签: node.js mongodb angular mongoose

状况:

我的Mongoose模型或其中一个传递给路线的参数似乎一定是犯了错误。

我对angular2架构还不熟悉,所以错误可能很明显。

错误:

  ERROR: ValidationError: CastError: Cast to ObjectID failed for value "{ title: 'das',
      username: 'John',
      choice1: 'FSDAFASDF',
      choice2: 'FDSAFD',
      counter1: 11,
      counter2: 0,
      pollId: '5920598ade7567001170c810',
      userId: '591c15b3ebbd170aa07cd476' }" at path "poll"

CODE:

路线

router.patch('/', function (req, res, next) {
    var decoded = jwt.decode(req.query.token);
    User.findById(decoded.user._id, function (err, user) {
      user.votes = req.body.votes;
      user.save(function(err, result) {
          if (err) {
              console.log("ERROR: "+err);
              return res.status(500).json({
                  title: 'An error occurred',
                  error: err
              });
          }
          res.status(201).json({
              poll: 'Vote Saved',
              obj: result
          });
      });
   });
});

模型/用户:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var mongooseUniqueValidator = require('mongoose-unique-validator');

var schema = new Schema({
    firstName: {type: String, required: true},
    lastName: {type: String, required: true},
    password: {type: String, required: true},
    email: {type: String, required: true, unique: true},
    polls: [{type: Schema.Types.ObjectId, ref: 'Poll'}],
    votes: [{
      poll: {type: Schema.Types.ObjectId, ref: 'Poll'},
      choice: {type: Number},
    }],
});

schema.plugin(mongooseUniqueValidator);

module.exports = mongoose.model('User', schema);

模型/轮询

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var User = require('./user');

var schema = new Schema({
    title: {type: String, required: true},
    choice1: {type: String, required: true},
    choice2: {type: String, required: true},
    counter1: {type: Number, required: true},
    counter2: {type: Number, required: true},
    user: {type: Schema.Types.ObjectId, ref: 'User'}
});

schema.post('remove', function (poll) {
    User.findById(poll.user, function (err, user) {
        user.polls.pull(poll);
        user.save();
    });
});

module.exports = mongoose.model('Poll', schema);

修改

router.patch('/', function (req, res, next) {
    var decoded = jwt.decode(req.query.token);
    console.log("VALID ID ? :"+mongoose.Types.ObjectId.isValid(decoded.user._id));
    console.log("DECODED USER ID:"+ decoded.user._id);
    User.findByIdAndUpdate(decoded.user._id, {votes: req.body.votes}, function (err, user) {
      user.save(function(err, result) {
          if (err) {
              console.log("ERROR: "+err);
              return res.status(500).json({
                  title: 'An error occurred',
                  error: err
              });
          }
          res.status(201).json({
              poll: 'Vote Saved',
              obj: result
          });
      });
   });
});

1 个答案:

答案 0 :(得分:1)

我仔细猜测这段特殊代码是导致问题的因素:

    ...
    User.findById(decoded.user._id, function (err, user) {
      user.votes = req.body.votes;
      user.save(function(err, result) {
    ...

mongoose试图重新保存模型并用普通字符串覆盖它的_id属性,而它应该是ObjectId的一个实例。

请尝试使用findByIdAndUpdate,而不是使用保存来更新模型。如果这是有效的,那么我的猜测是正确的。

User.findByIdAndUpdate(decode.user._id, {votes: req.body.votes}, function (err, user) {

或者,将字符串_id手动转换为ObjectId

    ...
    User.findById(decoded.user._id, function (err, user) {
      user.votes = req.body.votes;
      user._id = mongoose.Types.ObjectId(user._id);
      user.save(function(err, result) {
    ...

首先是首选。