【问题标题】:How to get user-roles with sequelize?如何通过 sequelize 获取用户角色?
【发布时间】:2020-07-27 01:53:44
【问题描述】:

我有一个这样的现实:

在我的解析器中,我正在获取这样的实体:

users: async () => {
  const users = await db.user.findAll({
    include: [
      {
        model: db.userroles,
        include: [
          {
            model: db.roles,
            attributes: ['Name'],
          },
        ],
      },
    ],
  });

我记录我从数据库中得到的信息:

 console.log('users are', users[0].dataValues.userroles[0].dataValues.role.Name); // logs "users are developer"

这表明我获取了正确的角色。

我的 graphql 架构:

  type user {
    Id: ID!
    Email: String
    RoleId: Int!
    Password: String
    ChangedPassword: Boolean
    WeddingId: Int!
    AttendantId: Int
    role: [roles!]
  }

  type roles {
    Id: ID!
    Name: String!
  }

在操场上我发送这个:

{users
  {role
  {Name}}
}

结果:

  "data": {
    "users": [
      {
        "role": null
      }
    ]
  }
}

当我记录从数据库返回的整个用户对象时:

users are userroles {
  dataValues:
   { UserId: 1,
     RoleId: 1,
     role:
      roles {
        dataValues: [Object],
        _previousDataValues: [Object],
        _changed: {},
        _modelOptions: [Object],
        _options: [Object],
        isNewRecord: false } },
  _previousDataValues:
   { UserId: 1,
     RoleId: 1,
     role:
      roles {
        dataValues: [Object],
        _previousDataValues: [Object],
        _changed: {},
        _modelOptions: [Object],
        _options: [Object],
        isNewRecord: false } },
  _changed: {},
  _modelOptions:
   { timestamps: false,
     validate: {},
     freezeTableName: true,
     underscored: false,
     paranoid: false,
     rejectOnEmpty: false,
     whereCollection: null,
     schema: null,
     schemaDelimiter: '',
     defaultScope: {},
     scopes: {},
     indexes: [],
     name: { plural: 'userroles', singular: 'userrole' },
     omitNull: false,
     tableName: 'userroles',
     sequelize:
      Sequelize {
        options: [Object],
        config: [Object],
        dialect: [MysqlDialect],
        queryInterface: [QueryInterface],
        models: [Object],
        modelManager: [ModelManager],
        connectionManager: [ConnectionManager],
        importCache: [Object] },
     hooks: {} },
  _options:
   { isNewRecord: false,
     _schema: null,
     _schemaDelimiter: '',
     include: [ [Object] ],
     includeNames: [ 'role' ],
     includeMap: { role: [Object] },
     includeValidated: true,
     raw: true,
     attributes: undefined },
  isNewRecord: false,
  role:
   roles {
     dataValues: { Name: 'Developer' },
     _previousDataValues: { Name: 'Developer' },
     _changed: {},
     _modelOptions:
      { timestamps: false,
        validate: {},
        freezeTableName: true,
        underscored: false,
        paranoid: false,
        rejectOnEmpty: false,
        whereCollection: null,
        schema: null,
        schemaDelimiter: '',
        defaultScope: {},
        scopes: {},
        indexes: [],
        name: [Object],
        omitNull: false,
        tableName: 'roles',
        sequelize: [Sequelize],
        hooks: {} },
     _options:
      { isNewRecord: false,
        _schema: null,
        _schemaDelimiter: '',
        include: undefined,
        includeNames: undefined,
        includeMap: undefined,
        includeValidated: true,
        raw: true,
        attributes: [Array] },
     isNewRecord: false } }

我得到了我只是不知道如何呈现的角色?

我认为问题出在我的解析器中,我缺少另一组包含但我不知道如何编写它。

【问题讨论】:

    标签: javascript node.js graphql sequelize.js


    【解决方案1】:

    user 和roles 与userRoles 作为联结表具有多对多关系。如果你还没有,应该在user上定义这个关系:

    user.belongsToMany(roles, { through: userRoles })
    

    这会让你直接include角色:

    const users = await db.user.findAll({
      include: [
        db.roles,
      ],
    });
    

    【讨论】:

    • 不知道这个,谢谢!
    • 只是想到了一些东西,可能与上述工作无关,但只是出于好奇。不应该是 roles.belongsToMany(user, { through: userRoles }) 吗?
    • 关系总是单向的。对于多对多,您通常两者。 user.belongsToMany(roles) 允许您通过user.roles 访问用户的角色。 roles.belongsToMany(user) 允许您通过role.users 访问所有用户的角色。如果您不需要其中一个,则可以省略声明该关系。
    【解决方案2】:

    发布后,我注意到架构中存在一些问题。

    我将架构更改为:

      type roles {
        Id: ID!
        Name: String!
      }
    
      type userroles {
        RoleId: ID!
        UserId: ID!
        role: roles
      }
    
      type user {
        Id: ID!
        Email: String
        RoleId: Int!
        Password: String
        ChangedPassword: Boolean
        WeddingId: Int!
        AttendantId: Int
        userroles: [userroles!]
      }
    

    游乐场:

    {users
      {userroles
      {role
      {Name}}}
    }
    

    结果:

      "data": {
        "users": [
          {
            "userroles": [
              {
                "role": {
                  "Name": "Developer"
                }
              }
            ]
          }
        ]
      }
    }
    

    答案让我眼前一亮,但我专注于解析器中的代码。

    留下这个问题,以防有人有其他方法。

    【讨论】:

    • 更改名称...类型大写,属性/字段小写...type User { id: ID!, changedPassword ...
    • 事情是我正在使用 sequelize-auto,它会生成所有带有 lovercase 的表名。
    • 这不是 sequelize-auto 故障 - 现有数据库名称(重命名数据库表?)...至少您可以使用 -C, --camel Use camel case to name models and fields
    猜你喜欢
    • 2016-08-11
    • 1970-01-01
    • 2021-11-01
    • 2018-03-08
    • 2019-07-11
    • 1970-01-01
    • 2021-04-30
    • 2013-05-21
    • 2021-06-01
    相关资源
    最近更新 更多