Sails.js The same model from many to many associations

Sails.js.10 rc8

I have completely run out of ideas for this

I have a model called User, and I want to associate it in the collection with other users, such as a friend list. As a many-to-many association

//User.js friends: { collection: 'user', via: 'friends' } 

but when I run .populate('friends') it doesn't populate anything. Any ideas?

+7
model waterline
source share
4 answers

I believe that the best way to implement this is to actually add a link to id .

Check out this user model:

 module.exports = { attributes: { name: { type: 'string', required: true, minLength: 2 }, email: { type: 'email', required: true, unique: true }, friends: { collection: 'user', via: 'id' } } }; 

Now, if you run sails console , you can test the following commands:

 User.create({name:'test',email:' test@test.com '}).exec(console.log); 

It returns:

 { name: 'test', email: ' test@test.com ', createdAt: '2016-12-01T22:06:19.723Z', updatedAt: '2016-12-01T22:06:19.723Z', id: 1 } 

You created your first user. Let's create a few others:

 User.create({name:'test2',email:' test2@test.com '}).exec(console.log); 

Result:

  { name: 'test2', email: ' test2@test.com ', createdAt: '2016-12-01T22:06:40.808Z', updatedAt: '2016-12-01T22:06:40.808Z', id: 2 } 

Let's see what we have:

 User.find().populate('friends').exec(console.log); [ { friends: [], name: 'test', email: ' test@test.com ', createdAt: '2016-12-01T22:06:19.723Z', updatedAt: '2016-12-01T22:06:19.723Z', id: 1 }, { friends: [], name: 'test2', email: ' test2@test.com ', createdAt: '2016-12-01T22:06:40.808Z', updatedAt: '2016-12-01T22:06:40.808Z', id: 2 } ] 

Now create a user with a friend using the link to the first user. Note that I just pass one id, not an array:

 User.create({name:'test3',email:' test3@test.com ', friends:1}).exec(console.log); 

Now this is the result. Please note that "friends" are not displayed. This is by design.

 { name: 'test3', email: ' test3@test.com ', createdAt: '2016-12-01T22:07:34.988Z', updatedAt: '2016-12-01T22:07:34.994Z', id: 3 } 

Do a search with populate to see the current status:

 User.find().populate('friends').exec(console.log); 

Now we see that the third user has friends. The rest have an empty array.

  [ { friends: [], name: 'test', email: ' test@test.com ', createdAt: '2016-12-01T22:06:19.723Z', updatedAt: '2016-12-01T22:06:19.723Z', id: 1 }, { friends: [], name: 'test2', email: ' test2@test.com ', createdAt: '2016-12-01T22:06:40.808Z', updatedAt: '2016-12-01T22:06:40.808Z', id: 2 }, { friends: [ { name: 'test', email: ' test@test.com ', createdAt: '2016-12-01T22:06:19.723Z', updatedAt: '2016-12-01T22:06:19.723Z', id: 1 } ], name: 'test3', email: ' test3@test.com ', createdAt: '2016-12-01T22:07:34.988Z', updatedAt: '2016-12-01T22:07:34.994Z', id: 3 } ] 

Let me create a fourth one, this time with two friends:

 User.create({name:'test4',email:' test4@test.com ', friends:[1,2]}).exec(console.log); 

Result (again, friends property):

  { name: 'test4', email: ' test4@test.com ', createdAt: '2016-12-01T22:07:50.539Z', updatedAt: '2016-12-01T22:07:50.542Z', id: 4 } 

This time we passed an array of identifiers to friends . View current status:

 User.find().populate('friends').exec(console.log); [ { friends: [], name: 'test', email: ' test@test.com ', createdAt: '2016-12-01T22:06:19.723Z', updatedAt: '2016-12-01T22:06:19.723Z', id: 1 }, { friends: [], name: 'test2', email: ' test2@test.com ', createdAt: '2016-12-01T22:06:40.808Z', updatedAt: '2016-12-01T22:06:40.808Z', id: 2 }, { friends: [ { name: 'test', email: ' test@test.com ', createdAt: '2016-12-01T22:06:19.723Z', updatedAt: '2016-12-01T22:06:19.723Z', id: 1 } ], name: 'test3', email: ' test3@test.com ', createdAt: '2016-12-01T22:07:34.988Z', updatedAt: '2016-12-01T22:07:34.994Z', id: 3 }, { friends: [ { name: 'test', email: ' test@test.com ', createdAt: '2016-12-01T22:06:19.723Z', updatedAt: '2016-12-01T22:06:19.723Z', id: 1 }, { name: 'test2', email: ' test2@test.com ', createdAt: '2016-12-01T22:06:40.808Z', updatedAt: '2016-12-01T22:06:40.808Z', id: 2 } ], name: 'test4', email: ' test4@test.com ', createdAt: '2016-12-01T22:07:50.539Z', updatedAt: '2016-12-01T22:07:50.542Z', id: 4 } ] 

Now, how do you add a friend to an existing user? This is somehow strange: you must first find user, and then use the add function in the resulting model, and then save it. In my daytime code, I have a helper function that does just that. So here is an example:

 User.findOne(1).populate('friends').exec(function(err,u){ u.friends.add(3);u.save(function(err){ if(err) console.error(err);});}); 

Now in the console we do not see any results. Now check the contents of the user:

 User.find().populate('friends').exec(console.log); [ { friends: [ { name: 'test3', email: ' test3@test.com ', createdAt: '2016-12-01T22:07:34.988Z', updatedAt: '2016-12-01T22:07:34.994Z', id: 3 } ], name: 'test', email: ' test@test.com ', createdAt: '2016-12-01T22:06:19.723Z', updatedAt: '2016-12-01T22:09:41.410Z', id: 1 }, { friends: [], name: 'test2', email: ' test2@test.com ', createdAt: '2016-12-01T22:06:40.808Z', updatedAt: '2016-12-01T22:06:40.808Z', id: 2 }, { friends: [ { name: 'test', email: ' test@test.com ', createdAt: '2016-12-01T22:06:19.723Z', updatedAt: '2016-12-01T22:09:41.410Z', id: 1 } ], name: 'test3', email: ' test3@test.com ', createdAt: '2016-12-01T22:07:34.988Z', updatedAt: '2016-12-01T22:07:34.994Z', id: 3 }, { friends: [ { name: 'test', email: ' test@test.com ', createdAt: '2016-12-01T22:06:19.723Z', updatedAt: '2016-12-01T22:09:41.410Z', id: 1 }, { name: 'test2', email: ' test2@test.com ', createdAt: '2016-12-01T22:06:40.808Z', updatedAt: '2016-12-01T22:06:40.808Z', id: 2 } ], name: 'test4', email: ' test4@test.com ', createdAt: '2016-12-01T22:07:50.539Z', updatedAt: '2016-12-01T22:07:50.542Z', id: 4 } ] 

With this method, you can even add the same user to your friends collection!

 User.findOne(1).populate('friends').exec(function(err,u){ u.friends.add(1);u.save(function(err){ if(err) console.error(err);});}); 

Good luck

+1
source share

Your models should look like this:

 //User.js friends: { collection: 'friend', via: 'user' } //Friend.js user: { model: 'user' via: 'friends' } 

Also sails 10 rc8 are old. You must be on the sails 10.5

+2
source share

You should use .populate('friends') instead of .populate(friends)

0
source share

As it turned out, when you have many, many associations in the waterline, you should declare one of the models dominant. Since they are one and the same model, none of them dominates. While the connection table is being created, it is not possible to populate it.

0
source share

All Articles