1
votes

I want to 2 model, one is user that can belongs to multiple groups, and another is group that can has multiple users. This is my schemas and models, i don't know whether they the correct:

var Schema = mongoose.Schema;
var UserSchema = new Schema({            
        joinedGroups:[{type:Schema.Types.ObjectId, ref: 'Group'}]            
    }
    );

var GroupSchema = new Schema({        
    createdBy: {type: Schema.Types.ObjectId, ref: 'User'},
    joinedUsers:[{ type: Schema.Types.ObjectId, ref: 'User' }]        
});

var User = mongoose.model('User',UserSchema);
var Group = mongoose.model('Group',GroupSchema);

when receive POST of url:/api/groups with the body of user._id, I want to join this user to new create group, besides, i want to join this new created group to user's joinedGroups and finally i want to response the client of the new group with users in it. Follow is my code of doing this:

app.post('/api/groups', function(req, res){ console.log(req.body);

var userId = req.body.user_id;
var group = {
    createdBy : userId
};

Group.create(group, function(err,group){
    if(err){
        console.log('create group err');
        res.send(err);
    }
    else{
        console.log('create group success');
        User.update({_id: userId},
            {$push: {joinedGroups: group._id}},
            function(err,user){
                if(err){
                    console.log('update user err');
                    res.send(err);
                }
                else{
                    Group.update({_id: group._id},
                        {$push: {joinedUsers: user}},
                    function(err,group){
                        if(err){
                            console.log('update group err:' + err);
                            res.send(err);
                        }
                        else{
                            group.populate({path:'joinedUsers'},
                                function(err, group){
                                    if(err){
                                        console.log('populate group err');
                                        res.send(err);
                                    }
                                    else{
                                        console.log('populate group success');
                                        res.json(group);
                                    }
                                }
                            );
                        }
                    });
                }
            });
    }
});

});

I feel it's really complex, and it occur error :

 update group err:CastError: Cast to ObjectId failed for value "1" at path "joinedUsers"

So i want somebody help me with right solution to do this, thanks!

edit: I also want to support join user in to existed group in PUT /api/group/:group_id like below:

var userId = req.body.user_id;
var groupId = req.params.group_id;

how to do that? thanks!

1

1 Answers

0
votes

First of all, your realization is really complex and it can be simplified as this:

var userId = req.body.user_id; // this is an ObjectId

var group = {
  createdBy: userId,
  joinedUsers: userId
};

Group.create(group, function (err, group) {
  if (err || !group) {
    return res.send(err);
  }

  User.findById(userId, function (err, user) {
    if (err || !user) {
      return res.send(err);
    }

    user.joinedGroups.push(group._id);
    user.save(function (err) {
      if (err) {
        return res.send(err);
      }

      group.populate('joinedUsers', function (err, group) {
        if (err || group) {
          return res.send(err);
        }

        res.json(group);
      });
    });
  });
});

And the reason why you getting CastError error is: the update method returns 1 as second argument of callback if successfully updated. But your Group#joinedUsers filed expecting User reference.