Tuesday, 9 May 2017

Mongoose nested schemas

I'm creating an app where you log workouts and I'm having some problems with Mongoose.

I have two schemas, one for workouts and one for exercises. When the user adds a new exercise, I want it to be stored inside the workout, and I've been trying this in a bunch of ways.

For now, the exercises are saved in a different collection in my MongoDB (don't know if this is the best way to do it), and I thought that it should save the exercise inside the workout.exercises, but there is only the objectID. How do I resolve this? Have looked at the populate function, but can't figure out how to get it to work.

addExercises

export function addExercise(req, res) {
  if (!req.body.exercise.title) {
    res.status(403).end();
  }

  const newExercise = new Exercise(req.body.exercise);

  // Let's sanitize inputs
  newExercise.title = sanitizeHtml(newExercise.title);
  newExercise.cuid = cuid();
  newExercise.sets = [];

  newExercise.save((err, saved) => {
    if (err) res.status(500).send(err);
  });

  Workout
    .findOneAndUpdate(
      {cuid: req.body.exercise.workoutCUID},
      {$push: {exercises: newExercise}},
      {upsert: true, new: true},
      function (err, data) {
        if (err) console.log(err);
      });
}

getExercises

export function getExercises(req, res) {
  Workout.findOne({cuid: req.params.cuid}).exec((err, workout) => {
    if (err) {
      res.status(500).send(err);
    }
    console.log(workout);
    let exercises = workout.exercises;
    res.json({exercises});
  });
}

Workout

import mongoose from "mongoose";
const Schema = mongoose.Schema;
var Exercise = require('./exercise');

const workoutSchema = new Schema({
  title:     {type: 'String', required: true},
  cuid:      {type: 'String', required: true},
  slug:      {type: 'String', required: true},
  userID:    {type: 'String', required: true},
  exercises: [{ type: Schema.Types.ObjectId, ref: 'Exercise' }],
  date:      {type: 'Date', default: Date.now, required: true},
});

export default mongoose.model('Workout', workoutSchema);

Exercise

import mongoose from "mongoose";
const Schema = mongoose.Schema;
var Workout = require('./workout');

const exerciseSchema = new Schema({
  title:       {type: 'String', required: true},
  cuid:        {type: 'String', required: true},
  workoutCUID: {type: 'String', required: true},
  sets:        {type: 'Array', "default": [], required: true}
});

export default mongoose.model('Exercise', exerciseSchema);



via Daniel Böök

No comments:

Post a Comment