[NestJS] TypeORM + postgreSQL

woogiemon·2023년 3월 9일
0
post-thumbnail

Relationship

  1. One To One
  2. Many To One
  3. Many To Many

1. One To One

We also added @JoinColumn which is required and must be set only on one side of the relation. The side you set @JoinColumn on, that side's table will contain a "relation id" and foreign keys to target entity table.

어느 쪽을 통해서 다른 쪽의 정보를 받아올 것인지 생각해보고, 1:1 관계의 주인쪽에 @JoinColumn 을 붙여준다.

삽질 1. User 가 회원가입할 때, Brand 와 Join 되어서 나중에 user.brand.branId 이런식으로 정보를 불러올 수 있게 만들기

처음에는 그저 brandId : number 라는 값을 박아넣었는데, 이렇게 하니까 user.brand 를 했을 때 undefined 값이 나옴. 어리둥절잼

// User entity
@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @ManyToOne(() => Brand, brand => brand.users)
  brand: Brand;
}

// Brand entity
@Entity()
export class Brand {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @OneToMany(() => User, user => user.brand)
  users: User[];
}
import { ApiProperty } from '@nestjs/swagger';

export class CreateUserDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  brandName: string;
}
// UserService
@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
    @InjectRepository(Brand)
    private readonly brandRepository: Repository<Brand>,
  ) {}

  async createUser(userDto: CreateUserDto): Promise<User> {
    const brand = await this.brandRepository.findOne({ name: userDto.brandName });
    const user = this.userRepository.create({ ...userDto, brand });
    return this.userRepository.save(user);
  }
}

이걸 토대로 회원가입 로직을 수정했다.

public async register(request: RegisterRequest) {
    const brand = await this.brandRepository.findOne({
      where: { id: request.brandId },
    });

    const hashedPassword = await bcrypt.hash(request.password, 12);
    const createdUser = await this.userService.addUser({
      email: request.email,
      name: request.name,
      password: hashedPassword,
      brandId: brand.id,
    });
  	...
  }

이제 로그인한 사용자가 자유게시판에 글을 등록하면, 해당 brand의 해당 게시글을 찾아 등록할 수 있게 로직을 변경했다.

freeBoard.controller.ts

@HttpCode(HttpStatus.CREATED)
@UseGuards(JwtAuthGuard)
@Post('/insertFreeBoard')
async insertFreeBoard(
  @UserPayload() payload: Payload,
  @Body() request: InsertFreeBoardRequest,
): Promise<InsertFreeBoardResponse> {
  if (payload.name) {
    const user = await this.userService.fetchOneUser(payload.id);
    return await this.freeBoardService.insertFreeBoard(user, request);
  }
  ...
}

freeBoard.service.ts

async insertFreeBoard(
    user: UserEntity,
    request: InsertFreeBoardRequest,
): Promise<InsertFreeBoardResponse> {
	const writer = await this.userRepository.findOne({
  		where: { id: user.id },
	  	relations: ['brand'],
	});

    const newBoard = this.freeBoardRepository.create({
      title: request.title,
      content: request.content,
      writer: writer,
      brand: writer.brand,
    });
    const savedBoard = await this.freeBoardRepository.save(newBoard);
    this.logger.debug(writer.brand.name);
    return {
      id: savedBoard.id,
      title: savedBoard.title,
      content: savedBoard.content,
      created_at: savedBoard.created_at,
      updated_at: savedBoard.updated_at,
      writerId: savedBoard.writer.id,
      brandId: savedBoard.brand.id,
	};
}
profile
삽질 기록..

0개의 댓글