我正试图建立我的 User
graphql模型 followers
以及 following
要查询的属性。不过,我在sequelize中建立关系有困难。我在试着用 Follower
作为联接表建模并设置 BelongsToMany
但没能让它工作。有人能建议我做什么或指出我做错了什么吗?
我通过手动查询找到了一个临时解决方案,您可以在我的 User.model.ts
,但我相信有一个更好的方法来使用适当的配置。
我在graphql和sequelize、typegraphql和sequelize typescript以及postgresql周围使用typescript Package 器。
用户.model.ts
// VENDOR
import { ObjectType, Field, ID } from 'type-graphql';
import { Model, Table, Column, PrimaryKey, Unique, IsUUID, HasMany, DefaultScope, AllowNull, DataType, BelongsToMany } from 'sequelize-typescript';
// APP
import Post from '../post/post.types';
import Follower from '../follower/follower.types';
/**User model for GraphQL & Database */
@Table({ timestamps: false, tableName: 'users' }) // tell sequelize to treat class as table model
@DefaultScope(() => ({ include: [{ model: Post.scope(), as: 'posts' }] })) // tell sequelize to include posts in its default queries
@ObjectType() // tell GraphQL to treat class as GraphQL model
export default class User extends Model<User>{
@PrimaryKey
@Unique
@AllowNull(false)
@IsUUID(4)
@Column(DataType.UUID)
@Field(() => ID)
id: string;
@Unique
@AllowNull(false)
@Column
@Field()
ci_username: string;
@AllowNull(false)
@Column
@Field()
username: string;
@AllowNull(false)
@Column
@Field()
first_name: string;
@Column
@Field()
last_name: string;
@Column
@Field({ nullable: true })
profile_picture?: string;
// @BelongsToMany(() => User, { otherKey: 'user_id', as: 'followers', through: () => Follower })
// @Field(() => [User])
// followers: User[];
// MY TEMPORARY SOLUTION USING MANUAL QUERYING
@Field(() => [User])
get followers(): Promise<User[]> {
return Follower.findAll({ where: { user_id: this.id } })
.then(records => records.map(record => record.follower_id))
.then((follower_ids: string[]) => {
return User.findAll({ where: { id: follower_ids }});
})
}
// DOES NOT WORK, BUT I BELIEVE COULD POTENTIALLY LEAD TO BETTER SOLUTION
@BelongsToMany(() => User, { otherKey: 'follower_id', as: 'following', through: () => Follower })
@Field(() => [User])
following: User[];
@HasMany(() => Post)
@Field(() => [Post])
posts: Post[];
}
从动件.model.ts
// VENDOR
import { Model, Table, Column, PrimaryKey, Unique, IsUUID, AllowNull, DataType, Index, ForeignKey, AutoIncrement } from 'sequelize-typescript';
// APP
import User from '../user/user.types';
/**Follower model for Database */
@Table({ timestamps: false, tableName: 'followers' }) // tell sequelize to treat class as table model
export default class Follower extends Model<Follower>{
@PrimaryKey
@AutoIncrement
@Unique
@AllowNull(false)
@Column
id: number;
@AllowNull(false)
@IsUUID(4)
@Index
@ForeignKey(() => User)
@Column(DataType.UUID)
user_id: string;
@AllowNull(false)
@IsUUID(4)
@Index
@ForeignKey(() => User)
@Column(DataType.UUID)
follower_id: string;
}
graphql查询
{
users: allUsers {
id
username
first_name
last_name
following {
username
id
}
}
}
graphql响应/错误
{
"errors": [
{
"message": "Cannot return null for non-nullable field User.following.",
"locations": [
{
"line": 7,
"column": 5
}
],
"path": [
"users",
0,
"following"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"stacktrace": [
"Error: Cannot return null for non-nullable field User.following.",
" at completeValue (/Users/jsainz237/Projects/trueview/trueview-api/node_modules/graphql/execution/execute.js:560:13)",
" at /Users/jsainz237/Projects/trueview/trueview-api/node_modules/graphql/execution/execute.js:492:16"
]
}
}
}
],
"data": null
}
感谢您的帮助。
1条答案
按热度按时间sycxhyv71#
你需要写一个
@FieldResolver
手动解决关系并返回正确的数据。另一种解决方案是依赖orm功能和延迟关系—当返回的基实体包含一个promise作为字段时,那么当
.then()
调用时,它会自动获取数据库的关系。