6

I'm pretty new on Nodejs and sails. I'm implementing a server which is similiar to Twitter. In user model, there should be 2 fields: follower and following, and the 2 fields are association of the model 'user' itself.

My question is when the model have only 1 association, either follower or following, it works. However, when both follower and following included, there would be en error.

The code is something like this:

module.exports = {
   attributes: {
   alias: {
     type:'string',
     required: true,
     primaryKey: true
   },
   pwd: {
    type: 'string',
    required: true
   },
   follower: {
      collection: 'user',
      via: 'alias'
   },
   following:{
      collection: 'user',
      via: 'alias'
   }
}

The code will cause such error:

    usr/local/lib/node_modules/sails/node_modules/waterline/node_modules/waterline-schema/lib/waterline-schema/references.js:115
throw new Error('Trying to associate a collection attribute to a model tha
      ^
Error: Trying to associate a collection attribute to a model that doesn't have a Foreign Key. user is trying to reference a foreign key in user
at References.findReference (/usr/local/lib/node_modules/sails/node_modules/waterline/node_modules/waterline-schema/lib/waterline-schema/references.js:115:11)
at References.addKeys (/usr/local/lib/node_modules/sails/node_modules/waterline/node_modules/waterline-schema/lib/waterline-schema/references.js:72:22)
Travis Webb
  • 14,688
  • 7
  • 55
  • 109
Renyuan wang
  • 171
  • 2
  • 9
  • How are you populating your models in the controller code? If not using populateAll(), are you supplying an attribute name to populate()? – Alex Alksne May 02 '15 at 06:35
  • @AlexAlksne I populate like this:`User.find({alias:item.alias}).populate('follower').exec(console.log);` Actually,I just define 'following,' even never use it. Then the sails report the error when lifing. – Renyuan wang May 02 '15 at 07:00
  • Odd, everything seems correct. I'm stumped so far; it's not much but if you look at the line that's causing the error in references.js it has this comment: "If no matching attributes are found, throw an error because you are trying to add a hasMany attribute to a model where the association doesn't have a foreign key matching the collection." – Alex Alksne May 02 '15 at 07:30

1 Answers1

3

For such usage your model definition is incorrect, namely the via keywords. As per the waterline associations docs the via keyword references the other side of the association. So, for a follower the other side is following and vice-versa. In other words:

follower: {
  collection: 'user',
  via: 'following'
},
following:{
  collection: 'user',
  via: 'follower'
}

You can check a full working example at: https://github.com/appscot/sails-orientdb/blob/master/test/integration-orientdb/tests/associations/manyToMany.selfReferencing.js

Dário
  • 2,002
  • 1
  • 18
  • 28
  • Thanks for your example. It definitely what I need. But I think there should be the same problem in some situation. Consider there are 2 groups defined, one is guys he hates, and another is guys he love. So the model should like this: `{ alias: 'string' hate: { collection: 'user', via: 'alias' }, love: { collection: 'user', via: 'alias' } }` It will cause the same problem, won't it? How can I avoid it? – Renyuan wang May 13 '15 at 04:26
  • I think you'll need to create 2 distinct self-referencing associations. One association would be `loves` / `lovedBy` and another would be `hates` / `hatedBy`. Hope that helps! – Dário May 13 '15 at 14:30