CastError:转换为ObjectId失败的值...`在路径"问题"

时间:2017-03-22 16:09:07

标签: javascript node.js mongodb mongoose

我目前正在使用MongoDB / Mongoose构建一个Node后端,我似乎遇到了将数据绑定在一起的问题。具体来说,我希望所有用户都能够提交一份表格(问题表格),然后将其添加到"问题"采集。除了被添加到问题集之外,我还需要存储对用户直接在用户对象内回答的所有问题的引用。

您可以在下面查看我的代码。每当我向POST发出/questions请求时,它都会吐出此错误。我应该注意到它成功地将文档添加到问题集中,每个问题都包含创建它的用户的ID,但主要问题是用户的questions数组没有得到更新包括已提交问题的ID值。

模型/ user.js的

const mongoose = require('mongoose'),  
      Schema = mongoose.Schema,
      bcrypt = require('bcrypt-nodejs');


const UserSchema = new Schema({  
  email: {
    type: String,
    lowercase: true,
    unique: true,
    required: true
  },
  password: {
    type: String,
    required: true
  },
  profile: {
    firstName: { type: String },
    lastName: { type: String }
  },
  questions: [
  {
      type: Schema.Types.ObjectId,
      ref: 'Question'
  }
],
  role: {
    type: String,
    enum: ['Member', 'Client', 'Owner', 'Admin'],
    default: 'Member'
  },
  resetPasswordToken: { type: String },
  resetPasswordExpires: { type: Date }
},
{
  timestamps: true
});

/** Pre-save of user to database, 
    hash password if password is modified or new 
*/
module.exports = mongoose.model('User', UserSchema);

模型/ Question.js

const mongoose = require('mongoose'),  
      Schema = mongoose.Schema;

// Schema defines how questions will be stored in MongoDB
const QuestionSchema = new Schema({
  questionString: String,
  answer: Boolean,
  _createdBy : [
  {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'User'
  }
],
},{
  //user timestamps to save date created as .createdAt   
  timestamps: true
});


module.exports = mongoose.model('Question', QuestionSchema);

控制器/ QuestionController.js

const jwt = require('jsonwebtoken'),  
      crypto = require('crypto'),
      Question = require('../models/question'),
            User = require('../models/user'),
      config = require('../config/main');


function setQuestionInfo(request) {  
  return {
    _id: request._id,
    questionString: request.questionString,
    answer: request.answer,
    user: request.user
  }
}

exports.addQuestion = function(req, res, next) {  

User.findById(req.user.id, (err, user) => {
if (err) throw new Error(err);

// We create an object containing the data from our post request
  const newQuestion = {
    questionString: req.body.questionString,
    answer: req.body.answer,
    // in the author field we add our current user id as a reference
    _createdBy: req.user._id
  };

  // we create our new post in our database
  Question.create(newQuestion, (err, question) => {
      if (err) {
        res.redirect('/');
        throw new Error(err);
      }

      // we insert our newQuestion in our posts field corresponding to the user we found in our database call
      user.questions.push(newQuestion);
      // we save our user with our new data (our new post).
      user.save((err) => {
        return res.send('sucess!');
      });
    })
  });
}

Router.js

module.exports = function(app) {
  // Initializing route groups
  const apiRoutes = express.Router(),
        userRoutes = express.Router(),
        authRoutes = express.Router(),
        questionRoutes = express.Router();

  //=========================
  // Auth Routes
  //=========================

  /** ROUTES BELOW WORK FINE -- ONLY DEALS WITH POST TO /questions
   * 


  app.use middle ware sets /auth as auth route (everything goes through /api/auth)
  apiRoutes.use('/auth', authRoutes);
  apiRoutes.get('/dashboard', requireAuth, function(req, res) {  
    res.send('It worked! User id is: ' + req.user._id + '.');
  });


  // Set user routes as a subgroup/middleware to apiRoutes
  apiRoutes.use('/user', userRoutes);

  // View user profile route
  userRoutes.get('/:userId', requireAuth, UserController.viewProfile);

  // Test protected route
  apiRoutes.get('/protected', requireAuth, (req, res) => {
    res.send({ content: 'The protected test route is functional!' });
  });
  // Registration route
  authRoutes.post('/register', AuthenticationController.register);
  // Login route
  authRoutes.post('/login', requireLogin, AuthenticationController.login);
  */

  // Problem Area --> Making POST req to /questions
  apiRoutes.post('/questions', requireAuth, QuestionController.addQuestion);

  // Set url for API group routes
  app.use('/api', apiRoutes);
};

1 个答案:

答案 0 :(得分:1)

您的架构已定义为接受用户的问题ID。

questions: [
  {
      type: Schema.Types.ObjectId,
      ref: 'Question'
  }

使用Question.create(newQuestion, (err, question)...保存后,回调属性question包含已更新的数据,其中一个数据为ObjectId

现在,您将此ObjectId值添加到questions模型findById上的现有User数组中。

user.questions.push(question._id);

当您在问题数组上使用questionId时,Mongoose将使用populate来填充您的问题对象,但这部分用于检索信息。