manutdfan
manutdfan

Reputation: 295

MEAN stack: How to create routes for nested relationships?

I have two models User and Plans. User has many plans so in my Mongoose Schema for plans I am embedding a userID like below.

var PlanSchema = new mongoose.Schema({
   title: {type: String},
   userId: {type: String},
   spots:[{
     name: {type: String},
     category: {type: String},
     address: {type: String},
     hours: {type: String},
     phone: {type: String},
     website: {type: String},
     notes: {type: String},
     imageUrl: {type: String},
     dayNumber: {type: Number}
   }]
});

I have two separate controllers in different files(users.js and plans.js) handling api route for both users and plans(/api/users and /api/plans).

I am struggling in figuring out how I can find plans for a specific user if I have their user ID.

Should I create a route /api/users/:id/plans in the users controller or is there a way to create a search route in plans.js controller like /api/plans/search?=

Or is there a different way?

Here is my plans controller code:

Plans

// Routes
PlansController.get('/', function(req, res){
  Plan.find({}, function(err, plans){
  res.json(plans);
  });
});

PlansController.get('/:id', function(req, res){
  Plan.findOne({_id: req.params.id}, function(err, plan){
    res.json(plan);
  });
});



PlansController.delete('/:id', function(req, res){
  var id = req.params.id;
  Plan.findByIdAndRemove(id, function(){
    res.json({status: 202, message: 'Success'});
  });
});

PlansController.post('/', function(req, res){
  var plan = new Plan(req.body);
  plan.save(function(){
    res.json(plan);
  });
});

PlansController.patch('/:id', function(req, res){
  Plan.findByIdAndUpdate(req.params.id, req.body, {new: true}, function(err, updatedPlan){
    res.json(updatedPlan);
  });
});

Not sure what is the best approach. Would greatly appreciate some input.

Upvotes: 0

Views: 101

Answers (1)

Tushar Arora
Tushar Arora

Reputation: 1146

1) If you want to create this path '/api/users/:id/plans' then you need to embed array of plans into user schema like this -

var Schema = mongoose.Schema;

var UserSchema = new mongoose.Schema({
  ...
  plans: { type: [Schema.ObjectId], ref: 'Plan' },
  ...
});
mongoose.model('User', UserSchema);

Now you can easily populate plans from Plan model by running this query -

User.findOne({ _id: userId})
  .populate('plans')
  .exec(function(err, user){
    //do stuff
  });

If the number of plans a user can have are not indefinite then you can use this because mongodb document has a size limit of 16 MB and arrays that grow beyond bounds should not be included in the schema.

2) For using '/api/plans/search?userid=' you need to store userId in Plan schema. You should make some changes in your schema as mentioned below.

 var PlanSchema = new mongoose.Schema({
   title: {type: String},
   userId: { type: Schema.ObjectId, ref: 'User' },
   spots:[{
     name: {type: String},
     category: {type: String},
     address: {type: String},
     hours: {type: String},
     phone: {type: String},
     website: {type: String},
     notes: {type: String},
     imageUrl: {type: String},
     dayNumber: {type: Number}
   }]
});

So that in future if you need user data you can easily populate it using the same method mentioned above without running nested queries.

Hope that helps.

Upvotes: 1

Related Questions