首页 > 解决方案 > 当父母有许多孩子时,对父母和孩子的“位置”进行续集

问题描述

我有 2 个模型:

class User extends Model {
    static associate(models) {
      User.hasMany(models.Role, {
        foreignKey: 'userId'
      });
    }
  };
  User.init({
    firstname: {
      type: DataTypes.STRING,
    },
    lastname: {
      type: DataTypes.STRING,
    },
    allowedApps: {
      type: DataTypes.ENUM({
        values: Object.keys(PORTALS)
      }),
      allowNull: false
    }
  }, {
    sequelize,
    paranoid: true,
    modelName: 'User',
  });

class Role extends Model {
    static associate(models) {
      Role.BelongsTo(models.User, {
        foreignKey: 'userId'
      });
    }
  };
  Role.init({
    type: {
      type: DataTypes.STRING,
      unique: true
    },
    name: DataTypes.STRING,
    userId: {
      type: DataTypes.INTEGER,
      allowNull: false,
    }
  }, {
    sequelize,
    paranoid: true,
    modelName: 'Role',
  });

我想获取名字或角色类型与特定条件匹配的所有用户。就像是:

User
    .findAndCountAll({
        where: {
            $or: [
         {
            firstname: "John Doe"
         },
         {
            "$Role.type$": "Admin"
         }
       ]
        },
        include: [{
            model: Role,
        }],
    }).limit=10,offset=0
    .then(users => res.status(200).send(users))
    .catch(error => {
        return res.sendStatus(500);
    });

上面的查询给了我错误:“SequelizeDatabaseError:'字段列表'中的未知列'Role.type'”

当子模型具有一对多关系且我的限制和偏移完好无损时,我想通过子模型进行搜索。如果用户与角色有HasOne关系,则相同的查询会给我成功。这只是我尝试实现的示例代码,因此请忽略任何拼写错误和愚蠢的错误。

标签: mysqlnode.jssequelize.js

解决方案


经过一番挖掘:

await User.findAll({
where: {
            $or: [
         {
            firstname: "John Doe"
         },
         {
            "$Role.type$": "Admin"
         }
       ]
        },
  include: {
    model: Role,
    as: 'Role',
    required: false
  }
});

但是,选择没有关联角色 ( required: false) 的用户并使用角色上存在的属性($ 或:$Role.type$)查询此类用户时,这在逻辑上没有意义。如果我们设置Required = true,那么我们违反了你的初始条件

名字或角色类型匹配特定条件。

下面解决了这个问题:

await User.findAll({
  include: {
    model: Role,
    required: false
  }
})
.then(
  users => users
    .filter(user => user?.firstName === "John Doe" || user.role?.type === 
    "Admin");
);

推荐阅读