简体   繁体   中英

Sequelize self-referential many-to-many; how to specify what I'm joining on

I have a Sequelize structure that associates my User table to itself through a Follow table, with follower and following . I'm 99% certain that I have all of the necessary pieces for this to be working the way I expect it to; I've the aliased

User.belongsToMany(models.User, { through: models.Follow, as: 'Followers', foreignKey: 'follower'});
User.belongsToMany(models.User, { through: models.Follow, as: 'Following', foreignKey: 'following'});

as well as

User.hasMany(models.Follow, { foreignKey: 'following' });
User.hasMany(models.Follow, { foreignKey: 'follower' });

and

Follow.belongsTo(models.User, { foreignKey: 'following', as: 'Following' });
Follow.belongsTo(models.User, { foreignKey: 'follower', as: 'Follower' });

And I'm able to call

User.findByPk(id, {
  include: {
    model: Follow
  }
});

which returns a single user and an array of Follow entries.
The problem I'm having is, Sequelize seems to be defaulting to creating the Follow query as where: { followING: User.id } rather than where: followER , such that if I have 1 user FOLLOWING themselves and 2 other people, but only FOLLOWED BY themselves, it only returns 1 result from my Follow table. As I was cycling through the primary keys for the handful of users in my seed, only the following value in my results change, such that I'm only ever returning a users' followers, not the other users that user is following.
Is there a way to specify in an include which specific column I'm trying to join on, when multiple columns match the Sequelize object to which I'm joining?
I understand that worst case scenario I can always skip the User step and go straight to

Follow.findAll({
  where: {
    follower: id
  }
})

But that restricts my immediate access to the User object and I'd have to write an additional query, which seems cumbersome considering a self-associated many-to-many capability exists.

If you wish to get a user with followers or with following users you don't need to indicate Follow table. All you need is to indicate an alias of a required association:

User.findByPk(id, {
  include: {
    model: User,
    as: 'Followers'
  }
});
User.findByPk(id, {
  include: {
    model: User,
    as: 'Following'
  }
});

In case you need to include Follow directly you need to add an associations like this:

User.hasMany(models.Follow, { as: 'FollowerLinks', foreignKey: 'follower'});
User.hasMany(models.Follow, { as: 'FollowingLinks', foreignKey: 'following'});

And you also should indicate an alias so that way Sequelize will know what association to use:

User.findByPk(id, {
  include: {
    model: Follow,
    as: 'FollowerLinks'
  }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM