GraphQl/Sequalize将多个hasMany/BelongTomany组合到单个列表中
我目前正在做一个项目,让玩家在1v1或2v2的概念中互相玩游戏 因此,我创建了以下两个sequelize类: player.jsGraphQl/Sequalize将多个hasMany/BelongTomany组合到单个列表中,graphql,sequelize.js,Graphql,Sequelize.js,我目前正在做一个项目,让玩家在1v1或2v2的概念中互相玩游戏 因此,我创建了以下两个sequelize类: player.js export class Player extends Model { static init(sequelize, DataTypes) { return super.init( { id: { type: DataTypes.INTEGER, primaryKey: true
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' });
}
}
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'
});
}
}
game.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' });
}
}
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
}
`
现在,当你查询玩家时,我试图让你得到所有的游戏,无论他是玩家1\u team1,玩家2\u team2
但我在想如何做到这一点时有点受阻:/
我尝试添加将4个数组组合到我的类中的getGames()
,但我没有找到如何调用此方法
getGames() {
return [...this.games1, ...this.games2, ...this.games3, ...this.games4];
}
我尝试搜索一种方法,您可以使用一个别名来查询,该别名组合了4个孩子(player1_team1…),但没有成功(在GraphQl中仍然是新的)
有人能帮我吗?游戏是一门课。调用newgame
或类似Game.create的静态方法生成类的实例。所以我们有
const Game = require('the location of the model')
const game = new Game()
在本例中,静态方法将在Game
变量上可用,因为它们应用于类,而不是该类的实例。同样,您在类中定义的非静态方法将在实例上可用,而不是在类上可用(即game
变量)
该方法在两个模型之间创建关联,并返回类的实例。通过这样写:
this.games1 = this.hasMany(Game, { ... })
您正在设置games1
static属性,因为这是在静态方法中进行的。因此,该属性在类而不是实例上可用。将结果关联对象保存到静态属性可能会有所帮助,但也不是必需的。你可以很容易地做到:
this.hasMany(Game, { ... })
重要的一点是,通过调用hasMany
,实际上是在类的实例上创建一个getter。在这种情况下,4个getter将根据您提供的别名命名为getPlayer1_team1
,getPlayer2_team1
,getPlayer1_team2
和getPlayer2_team2
因此,您可以添加如下方法:
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()
如果您的模式在Player
类型上公开了一个games
字段,您可以在该字段的解析器中执行此操作:
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 },
]
})
注意:重要的是要包含与定义关联时使用的值相同的。生成的player
变量现在将具有关联游戏的4个属性(player1\u team1
,player1\u team2
,等等)
如果您在获取Player实例时像这样懒洋洋地加载关联的游戏,现在可以执行类似操作来解析GraphQL中的Games
字段:
function resolve(parent, args, context, info) {
return [
...parent.player1_team1,
...parent.player1_team2,
...parent.player2_team1,
...parent.player2_team2,
]
}
另外,您可能应该将初始化模型的映射传递给associate
方法,这样就不必处理循环依赖关系。