thinky icon indicating copy to clipboard operation
thinky copied to clipboard

Can I reuse hasAndBelongsToMany relationship with same Model?

Open ironhee opened this issue 10 years ago • 6 comments

I want to use User_User_following table to handle user.followings and user.followers.

const User = thinky.createModel('User', {
  id: type.string(),
});

User.hasAndBelongsToMany(User, 'followings', 'id', 'id', {
  type: 'followings',
});
User.hasAndBelongsToMany(User, 'followers', 'id', 'id', {
  type: 'followers',
});

This implementation create different two relationship. I need to use one relationhip and reuse that.

const User = thinky.createModel('User', {
  id: type.string(),
});

User.hasAndBelongsToMany(User, 'followings', 'id', 'id', {
  backref: 'followers',  // I need this part!
});

Like this.

From now on, Creating relation with same model several time is available by options.type. But reuse hasAndBelongsToMany relationship is unable. (I think)

Can I reuse hasAndBelongsToMany relation?

ironhee avatar Jan 12 '16 08:01 ironhee

You can use type in the options http://thinky.io/documentation/api/model/#hasandbelongstomany

neumino avatar Jan 13 '16 02:01 neumino

But type option create 'different' relationship. What I need is use same relationship table.

ironhee avatar Jan 13 '16 04:01 ironhee

Oh, what you want is non bidirectional n-n relations. Thinky currently doesn't support that. I think you have to sneak another table for now and use 2 hasAndBelongsToMany. Being able to save custom fields in the relation could solve your problem too, but it's not yet available.

neumino avatar Jan 13 '16 15:01 neumino


const User = thinky.createModel('User', {
  id: type.string(),
});

User.hasAndBelongsToMany(User, 'followings', 'id', 'id', {
  type: 'followings',
});
User.hasAndBelongsToMany(User, 'followers', 'id', 'id', {
  type: 'followers',
});

User.define('follow', function(targetUser) {
  return Promise.all([
    this.addRelation('followings', { id: targetUser.id }).run(),
    targetUser.addRelation('followers', { id: this.id }).run(),
  ]);
});
User.define('unfollow', function(targetUser) {
  return Promise.all([
    this.removeRelation('followings', { id: targetUser.id }).run(),
    targetUser.removeRelation('followers', { id: this.id }).run(),
  ]);
});

From now on, I think this pattern can temporary solve that problem. :D Thank you!

ironhee avatar Jan 14 '16 02:01 ironhee

How you get only the 'followings'?

User.get('a user id').getJoin({ followings: true }).execute() //return b in "followings" 
User.get('b user id').getJoin({ followings: true }).execute() //return a in "followings" 

I need to get this result:

User.get('a user id').getJoin({ followings: true }).execute() //return b in "followings" 
User.get('b user id').getJoin({ followings: true }).execute() //return empty  "followings" 

SagiUziel avatar Sep 16 '16 07:09 SagiUziel

@SagiUziel I had same problem about that.

Thinky is really good library and handle so many things. But In that case, I can't find a way to handle that issue.

So I just create new library for rethinkdb and use that. In nothinkdb, Handling n-m relation by explicitly defined relationship table.

If you interested in how nothinkdb solve that problem, refer this

ironhee avatar Sep 19 '16 17:09 ironhee