首页 > 解决方案 > Sequelize - 使用连接表查询

问题描述

我正在使用权限构建基于角色的身份验证。我有以下表格 :UsersGroups和。GroupPermissionsPermissions

Users模型:

module.exports = (sequelize, DataTypes) => {
    var User = sequelize.define('User', {
        id: {
            primaryKey: true,
            type: DataTypes.UUID,
            defaultValue: DataTypes.UUIDV4,
        },
        email: DataTypes.STRING,
        password: DataTypes.STRING,
    }, {});

    User.associate = function(models) {
        User.belongsTo(models.Group, { as: 'group', foreignKey: 'groupId' });
    };

    return User;
};

Group模型:

module.exports = (sequelize, DataTypes) => {
    var Group = sequelize.define('Group', {
        id: {
            primaryKey: true,
            type: DataTypes.UUID,
            defaultValue: DataTypes.UUIDV4,
        },
        name: DataTypes.STRING,
    }, {
        timestamps: false,
    });

        Group.associate = function(models) {
        Group.hasMany(models.User, { foreignKey: 'groupId' });
    };

    return Group;
};

GroupPermission模型:

    module.exports = (sequelize, DataTypes) => {
        var GroupPermission = sequelize.define('GroupPermission', {
            id: {
                primaryKey: true,
                type: DataTypes.UUID,
                defaultValue: DataTypes.UUIDV4,
            },
            groupId: {
                type: DataTypes.UUID,
                allowNull: false,
            },
            permissionId: {
                type: DataTypes.UUID,
                allowNull: false,
            }
        }, {});

        GroupPermission.associate = function(models) {
        };

        return GroupPermission;
    };

Permission模型:

module.exports = (sequelize, DataTypes) => {
    var Permission = sequelize.define('Permission', {
        id: {
            primaryKey: true,
            type: DataTypes.UUID,
            defaultValue: DataTypes.UUIDV4,
        },
        name: {
            type: DataTypes.STRING,
            unique: true,
            allowNull: false,
        },
        level: {
            type: DataTypes.TINYINT,
            allowNull: false,
        }
    }, {});

    Permission.associate = function(models) {
    };

    return Permission;
};

这是我获取所有用户的方法:

getAll(req, res) {
    return User
        .findAll({
            include: [
                {
                    model: Group,
                    as: 'group',
                },
            ]
        })
        .then(users => res.status(201).send({ users }))
        .catch(error => res.status(400).send(error));
},

这给了我:

{
    "users": [
        {
            "id": "03c50380-3f05-4d8d-893f-408a179fb993",
            "email": "johndoe@gmail.com",
            "password": "$2b$10$fP3BR14iSZRHs/sYi0QAVuh8Zno60GO1dOKbN4K7GkOdVod2EENfC",
            "groupId": "c89ef57e-da09-42c1-bb09-0d988a35dd97",
            "group": {
                "id": "c89ef57e-da09-42c1-bb09-0d988a35dd97",
                "name": "Admin"
            }
        }
    ]
}

我也想在属性permissions内部group或旁边group,但我无法弄清楚我做错了什么 - 使用查询或关联。我省略了我正在努力找出关联的代码,以免混淆任何有兴趣帮助我的人。

标签: node.jspostgresqlexpresssequelize.jssequelize-cli

解决方案


首先,您必须关联 Permission 和 Group 模型。我想你想通过多对多的通信GroupPermission

module.exports = (sequelize, DataTypes) => {
  var Group = sequelize.define('Group', {
    id: {
      primaryKey: true,
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4,
    },
    name: DataTypes.STRING,
  }, {
    timestamps: false,
  });

  Group.associate = function(models) {
    Group.hasMany(models.User, { foreignKey: 'groupId' });
    Group.belongsToMany(models.Permission, { as: 'permissions', through: models.GroupPermission, foreignKey: 'groupId', otherKey: 'permissionId' })
  };

  return Group;
};

module.exports = (sequelize, DataTypes) => {
  var GroupPermission = sequelize.define('GroupPermission', {
    id: {
      primaryKey: true,
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4,
    },
    groupId: {
      type: DataTypes.UUID,
      allowNull: false,
    },
    permissionId: {
      type: DataTypes.UUID,
      allowNull: false,
    }
  }, {});

  GroupPermission.associate = function(models) {
  };

  return GroupPermission;
};

module.exports = (sequelize, DataTypes) => {
  var Permission = sequelize.define('Permission', {
    id: {
      primaryKey: true,
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4,
    },
    name: {
      type: DataTypes.STRING,
      unique: true,
      allowNull: false,
    },
    level: {
      type: DataTypes.TINYINT,
      allowNull: false,
    }
  }, {});

  Permission.associate = function(models) {
    Permission.belongsToMany(models.Group, { through: models.GroupPermission, foreignKey: 'permissionId', otherKey: 'groupId' });
  };

  return Permission;
};

那么你就可以:

getAll(req, res) {
  return User
    .findAll({
      include: [
        {
          model: Group,
          as: 'group',
          include: [{
            model: Permission,
            as: 'permissions',
          }]
        },
      ]
    })
    .then(users => res.status(201).send({ users }))
    .catch(error => res.status(400).send(error));
}

我还没有测试过代码,但它应该给你的想法。


推荐阅读