简体   繁体   中英

many-to-many relationship - populating related data in query - Keystonejs

I am working on a keystonejs project here and am running into a problem with relationships between two models.

I have the below two models:

User model:

User.add({
    name: { type: Types.Name, required: true, index: true },
    email: { type: Types.Email, initial: true, required: true, index: true },
  number: { type: Types.Number, index: true },
    password: { type: Types.Password, initial: true, required: true }
}, 'Permissions', {
    isAdmin: { type: Boolean, label: 'Can access Keystone', index: true },
}, 'Groups', {
    groups: {type: Types.Relationship, ref: 'Group', many: true }
});

And I have a Group model

Group.add({
    name: { type: String, required: true, index: true },
    description: { type: String, initial: true, required: true, index: true}

});

I have a aggregate function that basically pulls all of the groups that have users in it

    User.model.aggregate({$group:{'_id':'$groups'}}).exec(function(err,data){
                console.log(data);
});

My problem is that the above aggregate only shows me my groups by their _id values and not their names.

How could I populate and show the names in the front end? Obviously the id's are necessary on the back end to reference but to the front end users that won't work.

Thanks

You can create what you want pretty easily so don't be discouraged. You just need a heads up on the '.populate()' function in mongoose. See example below.

User Model (slightly tidied - I removed the (strange?) nesting)

User.add({
    name: { type: Types.Name, required: true, index: true },
    email: { type: Types.Email, initial: true, required: true, index: true},
    number: { type: Types.Number, index: true },
    password: { type: Types.Password, initial: true, required: true },
    isAdmin: { type: Boolean, label: 'Can access Keystone', index: true },
    groups: {type: Types.Relationship, ref: 'Group', many: true }
});

Group Model -- note the Group.relationship({}) option I've added near the bottom for admin convenience (shows users which reference that group on the backend)

Group.add({
    name: { type: String, required: true, index: true },
    description: { type: String, initial: true, required: true, index: true}    
});

Group.relationship({ ref: 'User', path: 'users', refPath:'Groups'});

Controller getting a list of users with all their corresponding group information

 view.on('init', function(next) {
    keystone.list('User').model.find()
    .populate('groups')
    .exec(function(err, users) {
      if(err) {
        console.log(err);
        return next(err);
      } else {
        locals.data.users = users;
        next(err);
      }
    });
  });

Controller getting Users within a specific group to display on the frontend (you need the group ID first)

  view.on('init', function(next) {
    keystone.list('User').model.find()
    .where('Groups').in([array, of, group, ids])
    .populate('groups')
    .exec(function(err, users) {
      if(err) {
        console.log(err);
        return next(err);
      } else {
        locals.data.users = users;
        next(err);
      }
    });
  });

locals.data.users would return like this in each case:

[
  {
    _id: '',
    name: '',
    ...
    groups: [
      {
        _id: '',
        name: ''
        ...
      }
    ]
  }
]

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