gpt4 book ai didi

GraphQl/Sequelize 在单个列表中组合多个 hasMany/BelongsToMany

转载 作者:行者123 更新时间:2023-12-03 22:26:32 26 4
gpt4 key购买 nike

我目前正在做一个项目,我让玩家在 1v1 或 2v2 概念中互相玩游戏。

所以我创建了以下 2 个 sequelize 类:

player.js

export class Player extends Model {
static init(sequelize, DataTypes) {
return super.init(
{
id: {
type: DataTypes.INTEGER,
primaryKey: true
},

createdAt: DataTypes.DATE,
updatedAt: DataTypes.DATE,
gender: DataTypes.STRING,
firstName: DataTypes.STRING,
lastName: DataTypes.STRING
},
{
sequelize
}
);
}

// Associations
static associate() {
this.games1 = this.hasMany(Game, { as: 'player1_team1', foreignKey: 'player1Team1Id' });
this.games2 = this.hasMany(Game, { as: 'player1_team2', foreignKey: 'player1Team2Id' });
this.games3 = this.hasMany(Game, { as: 'player2_team1', foreignKey: 'player2Team1Id' });
this.games4 = this.hasMany(Game, { as: 'player2_team2', foreignKey: 'player2Team2Id' });
}
}

game.js
export class Game extends Model {
static init(sequelize, DataTypes) {
return super.init(
{
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true
},
createdAt: DataTypes.DATE,
updatedAt: DataTypes.DATE,

playedAt: DataTypes.DATE,

set1_team1: {
type: DataTypes.INTEGER,
allowNull: true
},
set1_team2: {
type: DataTypes.INTEGER,
allowNull: true
},

set2_team1: {
type: DataTypes.INTEGER,
allowNull: true
},
set2_team2: {
type: DataTypes.INTEGER,
allowNull: true
},

set3_team1: {
type: DataTypes.INTEGER,
allowNull: true
},
set3_team2: {
type: DataTypes.INTEGER,
allowNull: true
}
},
{
sequelize
}
);
}

// Associations
static associate() {
this.player1_team1 = this.belongsTo(Player, {
as: 'player1_team1',
foreignKey: 'player1Team1Id'
});
this.player1_team2 = this.belongsTo(Player, {
as: 'player1_team2',
foreignKey: 'player1Team2Id'
});
this.player2_team1 = this.belongsTo(Player, {
as: 'player2_team1',
foreignKey: 'player2Team1Id'
});
this.player2_team2 = this.belongsTo(Player, {
as: 'player2_team2',
foreignKey: 'player2Team2Id'
});
}
}

那么下面的GraphQl方案
gql`  
type Player {
id: ID!
firstName: String!
lastName: String!
games: [Game]
}

type Game {
id: ID!
player1_team1: Player!
player1_team2: Player!
player2_team1: Player!
player2_team2: Player!
}

type Query {
player(id: ID!): Player
}
`

现在,当您查询 Player 时,我试图让您获得所有游戏,无论他是 player1_team1、player2_team2 ...

但是我在弄清楚如何做到这一点时有点受阻:/

我尝试将组合 4 个数组的 getGames() 添加到我的类中,但我没有找到如何调用此方法
getGames() {
return [...this.games1, ...this.games2, ...this.games3, ...this.games4];
}

我尝试寻找一种方法,您可以使用组合了 4 个 child (player1_team1 ...)的别名进行查询,但没有成功(在 GraphQl 中仍然是新的)

有人可以帮我吗?

最佳答案

Game 是一个类。调用 new Game 或像 Game.create 这样的静态方法会生成类的实例。所以我们有

const Game = require('the location of the model')
const game = new Game()

在这个例子中,静态方法将在 Game 变量上可用,因为它们适用于类,而不是该类的实例。同样,您在类中定义的非静态方法将在实例上可用,而不是在类上可用(即 game 变量)。

hasMany 方法在两个模型之间创建关联并返回 HasMany 类的实例。通过写这个:
this.games1 = this.hasMany(Game, { ... })

您正在设置 games1 静态 属性,因为您在 静态方法 中执行此操作。因此,该属性在类上可用,而不是在实例上可用。将生成的关联对象保存到静态属性可能会有所帮助,但也不是必需的。你可以很容易地做到:
this.hasMany(Game, { ... })

重要的一点是,通过调用 hasMany ,您实际上是在类的实例上创建一个 getter。在这种情况下,4 个 getter 将根据您提供的别名( getPlayer1_team1 参数)命名为 getPlayer2_team1getPlayer1_team2getPlayer2_team2as

所以你可以添加一个方法,如:
async getGames() {
const [games1, games2, games3, games4] = await Promise.all([
this.getPlayer1_team1(),
this.getPlayer1_team2(),
this.getPlayer2_team1(),
this.getPlayer2_team2(),
])
return [...this.games1, ...this.games2, ...this.games3, ...this.games4]
}

然后从某个实例调用它:
const player = await Player.findByPk(1)
const games = await Player.getGames()

如果您的架构在 games 类型上公开了 Player 字段,您可以在该字段的解析器中执行此操作:
function resolve(parent, args, context, info) {
return parent.getGames()
}

或者...

您可以在获取玩家时延迟加载相关模型并获取游戏。这通常比获取玩家然后获取游戏更有效。因此,在获取播放器时,您可以执行以下操作:
const player = await Player.findByPk(1, {
include: [
{ as: 'player1_team1', model: Game },
{ as: 'player1_team2', model: Game },
{ as: 'player2_team1', model: Game },
{ as: 'player2_team2', model: Game },
]
})

注意:包含定义关联时使用的相同 as 值很重要。生成的 player 变量现在将有 4 个相关游戏的属性( player1_team1player1_team2 等)。

如果您在获取 Player 实例时像这样延迟加载关联的游戏,您现在可以执行以下操作来解析 GraphQL 中的 games 字段:
function resolve(parent, args, context, info) {
return [
...parent.player1_team1,
...parent.player1_team2,
...parent.player2_team1,
...parent.player2_team2,
]
}

关于GraphQl/Sequelize 在单个列表中组合多个 hasMany/BelongsToMany,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58154009/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com