2017-03-22 6 views
1

Ich baue gerade ein Knoten-Backend mit MongoDB/Mongoose und ich habe ein Problem mit dem Verknüpfen meiner Daten zu haben. Insbesondere möchte ich, dass alle Benutzer ein Formular (ein Frageformular) einreichen können, das dann zur Sammlung "Fragen" hinzugefügt wird. Zusätzlich zur Sammlung von Fragen muss ich auch einen Verweis auf alle Fragen speichern, die ein Benutzer direkt innerhalb des Benutzerobjekts beantwortet hat.CastError: Cast zu ObjectId fehlgeschlagen für Wert ... `at Pfad" Fragen "

Unten können Sie meinen Code überprüfen. Immer wenn ich eine POST Anfrage an /questions mache, spuckt es diesen Fehler aus. Ich sollte beachten, dass es erfolgreich Dokumente in die Fragen Sammlung hinzugefügt, und jede Frage enthält die ID des Benutzers, der es erstellt, aber das Hauptproblem ist die Benutzer questions Array wird nicht aktualisiert, um einen ID-Wert der eingereichten Fragen enthalten.

Modelle/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); 

Modelle/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); 

Controller/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); 
}; 
+0

Hallo Thomas Greco; Das ist ein _lot_ Code, den Sie dort eingefügt haben. Könnten Sie versuchen, es auf ein [minimales, vollständiges und verifizierbares Beispiel] (https://stackoverflow.com/help/mcve) zu überarbeiten? –

+1

Ich entschuldige mich, dass ich nicht bemerkt habe, dass ich das Modell für jede Sammlung zweimal hinzugefügt habe, aber ich ging durch und entfernte ein solides Stück Code, der nichts mit meiner Frage zu tun hatte. Ich habe nur den AuthController und andere auth-bezogene Sachen eingeschlossen, um zu zeigen, dass die API gut funktioniert (außer für diese Instanz: P) –

+1

Können Sie 'user.questions.push (question._id);' anstelle von 'user.questions versuchen .push (newQuestion); '? – Veeram

Antwort

1

Sie haben Ihr Schema für einen Benutzer zu akzeptieren Frage-IDs definiert.

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

Nachdem Sie mit Question.create(newQuestion, (err, question)... dem Callback-Attribute speichern question die aktualisierten Daten hat, einen mit den ObjectId.

Jetzt fügen Sie diesen ObjectId Wert zu Ihrem vorhandenen questions Array hinzu, das Sie von findById auf User Modell erhalten haben.

user.questions.push(question._id); 

Mongoose die questionId benutzen, um Ihre Frage Objekt zu füllen, wenn Sie populate auf Fragen Array verwenden, aber das ist Teil Informationen für die Beschaffung.

+0

Super. Ich danke dir sehr! –

Verwandte Themen