2

Does anyone know if it's possible to populate a list of IDs for another model using waterline associations? I was trying to get the many-to-many association working but I don't think it applies here since one side of the relationship doesn't know about the other. Meaning, a user can be a part of many groups but groups don't know which users belong to them. For example, I'm currently working with a model with data in mongodb that looks like:

// Group
{
  _id: group01,
  var: 'somedata',
},
{
  _id: group02,
  var: 'somedata',
},
{
  _id: group03,
  var: 'somedata',
}

// User
{
  _id: 1234,
  name: 'Jim',
  groups: ['group01', 'group03']
}

And I'm trying to figure out if it's possible to setup the models with an association in such a way that the following is returned when querying the user:

// Req: /api/users/1234
// Desired result
{ 
  id: 1234,
  name: 'Jim',
  groups: [
    {
      _id: group01,
      var: 'somedata',
    },
    {
      _id: group03,
      var: 'somedata',
    }
  ]
}
Jason Sims
  • 1,148
  • 2
  • 10
  • 22

1 Answers1

0

Yes, associations are supported in sails 0.10.x onwards. Here is how you can setup the models

Here is how your user model will look like:

// User.js

module.exports = {

  tableName: "users",
  attributes: {

    name: {
      type: "string",
      required: true
    },

    groups: {
      collection: "group",
      via: "id"
    }

  }

};

Here is how your group model will look like:

// Group.js
module.exports = {

  tableName: "groups",

  attributes: {

        name: {
            type: "string",
            required: "true"
        }   

  }

};

Setting up models like this will create three tables in your DB:

users, groups and group_id__user_group

The last table is created by waterline to save the associations. Now go on and create groups. Once groups are created, go ahead and create user. Here is a sample POST request for creation a new user

{
  "name": "user1",
  "groups": ["547d84f691bff6663ad08147", "547d850c91bff6663ad08148"]
}

This will insert data into the group_id__user_group in the following manner

{
    "_id" : ObjectId("547d854591bff6663ad0814a"),
    "group_id" : ObjectId("547d84f691bff6663ad08147"),
    "user_groups" : ObjectId("547d854591bff6663ad08149")
}

/* 1 */
{
    "_id" : ObjectId("547d854591bff6663ad0814b"),
    "group_id" : ObjectId("547d850c91bff6663ad08148"),
    "user_groups" : ObjectId("547d854591bff6663ad08149")
}

The column user_groups is the user id. And group_id is the group id. Now if you fetch the user using GET request, your response will look like this:

{
    "groups": [
        {
            "name": "group1",
            "createdAt": "2014-12-02T09:23:02.510Z",
            "updatedAt": "2014-12-02T09:23:02.510Z",
            "id": "547d84f691bff6663ad08147"
        },
        {
            "name": "group2",
            "createdAt": "2014-12-02T09:23:24.851Z",
            "updatedAt": "2014-12-02T09:23:24.851Z",
            "id": "547d850c91bff6663ad08148"
        }
    ],
    "name": "user1",
    "createdAt": "2014-12-02T09:24:21.182Z",
    "updatedAt": "2014-12-02T09:24:21.188Z",
    "id": "547d854591bff6663ad08149"
}

Please note that groups are not embedded in the user collection. Waterline does the fetch from groups, users and group_id__user_group to show this result to you.

Also, if you want to do this in your controller, you will need to execute like this

User.findOne({'id': "547d854591bff6663ad08149"})
.populate('groups')
.exec(function (err, user){
  // handle error and results in this callback
});

Without populate('groups'), you won't get the groups array. Hope this serves your purpose

Mandeep Singh
  • 7,674
  • 19
  • 62
  • 104