CiscoKidx
CiscoKidx

Reputation: 920

Should one-to-one associations populate both sides?

I have two models (user & agent). I then create a user and an agent. I am expecting to see the association when using the blueprint routes for BOTH /user and /agent. I am only seeing the user model is associated with an agent via the /agent blueprint. The /user blueprint does not have any reference/association to an Agent.

The issue presents itself when I am trying to access the Agent via A userId with the following command:

User.findOne(req.body.userId).populate('agent').exec(function(err, agent)

"agent" is in fact the user information...not the agent.

Here are my models:

User:

attributes: {
  agent: {
    model: 'agent',
    via: 'owner'
  }
}

Agent:

attributes: {
  owner: {
    model: 'user'
  }
}

Thanks for reading!

Upvotes: 1

Views: 251

Answers (2)

sgress454
sgress454

Reputation: 24948

Sails does not fully support one-to-one model associations--you have to set the "foreign key" on both sides. See https://stackoverflow.com/a/27752329/345484 for more information. I'm tempted to just close this question as a duplicate of that one, but the setup is slightly different.

Upvotes: 2

Eugene Obrezkov
Eugene Obrezkov

Reputation: 2986

You have understood the populate wrong. populate() doesn't replace last call with new information. It takes attribute from model (that you specify in populate('attribute')) and replace id of that attribute in your model with another model information looked up by its id.

Let's dive into example.

You have User and Agent model.

// api/models/User.js
module.exports = {
  attributes: {
    agent: {
      model: 'Agent',
      via: 'owner'
    }
  }
};

// api/models/Agent.js
module.exports = {
  attributes: {
    owner: {
      model: 'User',
      via: 'agent'
    }
  }
};

You are calling User.findOne(userId).populate('agent').exec(function(err, user) {} and expect to get only agent as I understood. Wrong. It returns User model with Agent model as an attributes of User model.

// api/controllers/AnyController.js
module.exports = {
  index: function(req, res) {
    User
      .findOne(req.param('userId'))
      .populate('agent')
      .then(function(user) {
        console.log(user); // User information
        console.log(user.agent); // Agent information for that user
        return user;
      })
      .then(res.ok)
      .catch(res.negotiate);
  }
};

You can read about population more here - http://mongoosejs.com/docs/populate.html

Upvotes: 1

Related Questions