Sequelize User M2M Group - Найти пользователей, которые находятся в группах - PullRequest
0 голосов
/ 04 октября 2018

В моем проекте у меня есть пользователи и группы, и у пользователя может быть несколько групп.У меня проблемы с фильтрацией списка пользователей по тем, кто входит в определенную группу.

Вот мои настройки:

Модель пользователя

module.exports = (sequelize) => {
  const model = sequelize.define('users',
  {
    id: {
      type: Sequelize.INTEGER,
      autoIncrement: true,
      primaryKey: true,
      field: 'uID',
    },
    username: {
      type: Sequelize.STRING, allowNull: false, unique: true, field: 'uEmail',
    },
  }, {
    timestamps: false,
    tableName: 'Users',
  });
  model.modelName = 'users';
  return model;
};

Модель группы

module.exports = (sequelize) => {
  const model = sequelize.define('groups', {
    id: {
      type: Sequelize.INTEGER,
      autoIncrement: true,
      primaryKey: true,
      field: 'gID',
    },
    name: { type: Sequelize.STRING, allowNull: false, field: 'gName' },
    description: { type: Sequelize.STRING, allowNull: false, field: 'gDescription' },
  }, {
    timestamps: false,
    tableName: 'Groups',
  });
  model.modelName = 'groups';
  return model;
};

M2M через таблицу :: Группы пользователей

module.exports = (sequelize) => {
  const model = sequelize.define('usergroups', {
  }, {
    timestamps: false,
    tableName: 'UserGroups',
  });
  model.modelName = 'usergroups';
  return model;
};

Ассоциация

User.belongsToMany(Group, {
  through: UserGroup,
  as: 'groups',
  foreignKey: 'uID',
});
Group.belongsToMany(User, {
  through: UserGroup,
  as: 'users',
  foreignKey: 'gID',
});

Мои пользователи БД выглядят так (сокращенно):
User1.groups = [1,2,3]
User2.groups = [1,3]
User3.groups = [2,3]

Я строю API остального поиска: GET /users?groups[]=1&groups[]=2

При создании запроса я пытался фильтровать на основегруппы, переданные в этом формате:

let query = {};
query.include = [
  {
    model: Group,
    as: 'groups',
    where: {id: {[Op.in]: filter.groups}},
    attributes: ['id', 'name'],
  },
];
const result = yield User.findAndCountAll(query);

или попытались использовать throughrequired: true или required: false):

let query = {};
query.include = [
  {
    model: Group,
    as: 'groups',
    through: { where: {'gID': {[Op.in]: filter.groups}}, required: true},
    attributes: ['id', 'name'],
  },
];
const result = yield User.findAndCountAll(query);

Это работает, за исключением возвращаемых объектовсвязанные группы сокращены.Если я передам этот фильтр:

GET /users?groups[]=1

Ответ возвращается с нужными пользователями, но группы, связанные с этими пользователями, фильтруются:

[
  {
    "id": 1,
    "username": "user1@site.com",
    "groups": [
      {
        "id": 1,
        "name": "My Group",
        "usergroups": {
           "uID": 1,
           "gID": 1
        }
      }
    ]
  },
  {
    "id": 2,
    "username": "user2@site.com",
    "groups": [
      {
        "id": 1,
        "name": "My Group",
        "usergroups": {
          "uID": 2,
          "gID": 1
        }
      }
    ]
  }
]  

Но где группы 2 и 3 для User1 и группа 2 для User2?

Это почти как если бы мне нужно было получить все идентификаторы пользователей в определенной группе (через класс обслуживания Group), а затем сделать:
query.where = {id: {[Op.in]: userIdsArray}}

...