0

I have two models. Project and Server. A project has many servers. Many Servers have one Project. This works great for servers. The project field is populated correctly. But the servers field in the Project is not populated.

The schemas look like this:

var ProjectSchema = new Schema({
    name: String,
    created: String,
    updated: String,
    servers: [{
        type: Schema.ObjectId,
        ref: 'Server'
    }]
});

var ServerSchema = new Schema({
    name: String,
    iheap: Number,
    mheap: Number,
    node: String,
    cell: String,
    cluster: String,
    stage: String,
    created: String,
    updated: String,
    project: {
        type: Schema.ObjectId,
        ref: 'Project'
    }
});

Server has the project field populated.

[
    {
        "_id": "55899afad599d0cabdfa60c7",
        "created": "2015-06-23T19:44:26+02:00",
        "stage": "Test",
        "cluster": "AppServerCluster01",
        "cell": "Cell01",
        "node": "Node01",
        "mheap": 1,
        "iheap": 1,
        "name": "a",
        "project": {
            "_id": "55899af1d599d0cabdfa60c6",
            "created": "2015-06-23T19:44:17+02:00",
            "name": "asd",
            "__v": 0,
            "servers": []
        },
        "__v": 0
    }
]

Servers field is not populated on a project

[
    {
        "_id": "55899af1d599d0cabdfa60c6",
        "created": "2015-06-23T19:44:17+02:00",
        "name": "asd",
        "__v": 0,
        "servers": []
    }
]

And this is how i do the populate. Projects:

exports.getProjects = function(req, res) {
    Project.find({}).populate("servers").exec(function(err, projects) {
        if(err) {
            console.log("Error: " + err);
            res.send(err);
        } else {
            console.log("Got projects " + projects);
            res.json(projects);
        }
    });
};

Servers:

exports.getServers = function(req, res)  {
    Server.find({}).populate('project').exec(function(err, servers) {
        if(err) {
            console.log('Error: ' + err);
            res.send(err);
        } else {
            res.json(servers);
        }
    });
};

This is how i do the insert

exports.createProject = function(req, res) {
    var project = new Project();
    project.name = req.body.name;
    project.created = moment().format();

    project.save(function(err) {
        if(err) {
            console.log("Error: " + err);
            res.send(err);
        } else {
            console.log("Project created. project: " + project);
            res.json({ 'message': 'Project greated', 'project': project });
        }
    });
};

exports.createServer = function(req, res) {
    var server = new Server();
    server.project = req.body.project;
    server.name = req.body.name;
    server.iheap = req.body.iheap;
    server.mheap = req.body.mheap;
    //server.node = req.body.node;
    //server.cell = req.body.cell;
    //server.cluster = req.body.cluster;
    server.node = "Node01";
    server.cell = "Cell01";
    server.cluster = "AppServerCluster01";
    server.stage = req.body.stage;
    server.created = moment().format();

    server.save(function(err) {
        if(err) {
            console.log('Error: ' + err);
            res.send(err);
        } else {
            console.log('Server created. ' + server);
            res.json({ "message": "Server created!", "server": server });
        }
    });

};
2
  • Are you actually adding a Server instance to a Project instance properly? Because it doesn't look like it judging by what's being stored in the database. In other words: show us the code where you relate both types of instances to each other. Commented Jun 24, 2015 at 11:39
  • @robertklep thanks for the reply. I've added additional code to my question. Commented Jun 24, 2015 at 11:56

1 Answer 1

1

Population in Mongoose operates using two distinct steps:

  • associating the related model instances
  • let Mongoose automatically populate (run the relevant queries for) the related properties

The association has to be done explicitly; in other words, you need to associate a Server model instance with a Project model instance manually.

Doing that for server instances looks okay:

server.project = req.body.project;

(I assume that req.body.project is the _id of the project?)

However, you're not creating the relation between Project and Server. Here is a (rather verbose) example on how you could do that:

exports.createServer = function(req, res) {
  var server = new Server({
    project : req.body.project,
    name    : req.body.name,
    iheap   : req.body.iheap,
    mheap   : req.body.mheap,
    node    : "Node01",
    cell    : "Cell01",
    cluster : "AppServerCluster01",
    stage   : req.body.stage,
    created : moment().format(),
  });

  server.save(function(err, serverInstance) {
    if(err) {
      console.log('Error: ' + err);
      res.send(err);
    } else {
      Project.findById(req.body.project, function(err, projectInstance) {
        if (err) {
          console.log('Error: ' + err);
          res.send(err);
        } else {
          // This is where the relation is made:
          projectInstance.servers.push(serverInstance);
          // We need to save the project instance because we changed it:
          projectInstance.save(function(err) {
            if (err) {
              console.log('Error: ' + err);
              res.send(err);
            } else {
              console.log('Server created. ' + server);
              res.json({ "message": "Server created!", "server": server });
            }
          });
        }
      });
    }
  });

};
Sign up to request clarification or add additional context in comments.

1 Comment

I didn't realize that i have to make the relation manually. Thank you for the excellent answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.