'How to save Column with @Afterload , Nested Relations TypeORM
I want to put the number of posts in my user profile entity.
- user_profile.entity.ts
@Entity()
@Unique(['username'])
export class UserProfile {
/** Columns */
@PrimaryGeneratedColumn('uuid')
readonly id: string;
@Column('timestamptz')
@CreateDateColumn()
readonly created_at: Date;
@Column('timestamptz')
@UpdateDateColumn()
readonly updated_at: Date;
@ApiProperty()
@Column({ length: 255 })
@IsString()
@Length(3, 50)
username: string;
@Column()
post_count: number;
@ApiProperty({ readOnly: true })
@Column('uuid')
@IsUUID('4')
user_id: string;
@ApiProperty({ readOnly: true })
@Column({ default: 0, nullable: true })
@IsOptional()
exp?: number;
@ApiProperty({ readOnly: true })
@Column({ default: 1, nullable: true })
@IsOptional()
level?: number;
/** Relations */
@OneToOne((type) => User, (user) => user.profile, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'user_id', referencedColumnName: 'id' })
user: User;
// ** Hooks
@AfterLoad()
updatePostCount() {
this.post_count = this.user.posts.length;
}
}
- user.entity.ts
@Entity()
@Unique(['email'])
@Check(`
COALESCE((provider = 'local')::integer, 0)
+
COALESCE(LENGTH(social_id::text)::boolean::integer, 0)
= 1
`)
export class User {
/** Columns */
@ApiProperty()
@PrimaryGeneratedColumn('uuid')
readonly id: string;
@ApiProperty()
@Column('timestamptz')
@CreateDateColumn()
readonly created_at: Date;
@ApiProperty()
@Column('timestamptz')
@UpdateDateColumn()
readonly updated_at: Date;
@ApiProperty()
@Column({ length: 255 })
@IsEmail()
email: string;
/** Relations */
@OneToMany((type) => Post, (post) => post.author)
posts: Post[];
@ApiProperty()
@OneToOne((type) => UserProfile, (userProfile) => userProfile.user, {
cascade: true,
})
profile: UserProfile;
@AfterLoad()
asdfasdf() {
console.log('유저 entity :');
}
}
- post.entity.ts
@Entity()
export class Post {
/** Columns */
@PrimaryGeneratedColumn('uuid')
readonly id: string;
@Column('timestamptz')
@CreateDateColumn()
readonly created_at: Date;
@Column('timestamptz')
@UpdateDateColumn()
readonly updated_at: Date;
@ApiProperty()
@Column({ length: 255 })
@IsString()
title: string;
@ApiProperty()
@Column('text')
@IsString()
contents: string;
@ApiProperty({ readOnly: true })
@Column('uuid')
@IsUUID('4')
user_id: string;
/** Relations */
@ManyToOne((type) => User, (user) => user.posts, {
cascade: true,
// eager: true,
onDelete: 'CASCADE',
})
@JoinColumn({ name: 'user_id', referencedColumnName: 'id' })
author: User;
}
- users.service.ts
async getMyUser(user_id: string) {
const test = await this.userProfileRepository
.createQueryBuilder('user_profile')
.leftJoinAndSelect('user_profile.user', 'user')
.leftJoinAndSelect('user.posts', 'posts')
.where('user.id = :id', { id: user_id })
.getOne();
return test;
}
async getUserProfile(user_id: string): Promise<UserProfileResponseDto> {
try {
const user = await this.userRepository
.createQueryBuilder('user')
.leftJoinAndSelect('user.profile', 'user_profile')
.leftJoinAndSelect('user.followers', 'followers')
.leftJoinAndSelect('user.following', 'following')
.leftJoinAndSelect('user.posts', 'posts')
.where('user.id = :id', { id: user_id })
.getOne();
if (!user) {
throw new Error();
}
return {
profile: user.profile,
followers: user.followers.length,
following: user.following.length,
posts: user.posts.length,
};
} catch (err) {
throw new BadRequestException('Invalid user_id');
}
}
In user_profile entity, I used @Afterload,
When I use userPrifileRepository(getMyUser), the output is good,
but if I use userRepository(getUserProfile), it doesn't come out. (this.user or this.user.posts.length was printed as undefined.)
And even if the output was good, it could not be saved.
this.post_count = this.user.posts.length
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
