import { Module } from '@nestjs/common';
import { BoardsController } from './boards.controller';
import { BoardsService } from './boards.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { BoardRepository } from './board.repository';
import { Board } from './board.entity';
import { AuthModule } from 'src/auth/auth.module';
@Module({
imports: [TypeOrmModule.forFeature([Board]), AuthModule],
controllers: [BoardsController],
providers: [BoardsService, BoardRepository],
})
export class BoardsModule {}
@Controller('boards')
@UseGuards(AuthGuard()) // 모든 게시물 요청에 토큰값으로 유저 정보를 가져온다.
export class BoardsController {
constructor(private boardsService: BoardsService) {}
...
이제부터는 토큰값이 없거나 유효하지 않으면 게시물에 대한 요청을 보낼때 에러가 내려간다.
관계를 형성하기 위해서는 엔티티에 서로간의 필드를 넣어줘야한다.
한 유저는 여러 개의 게시글을 작성할 수 있고,
한 게시글은 한명의 유저만을 가진다.
위와 같은 관계는 유저에서는 OneToMany, 게시글에서는 ManyToOne 관계를 가진다.
import {
BaseEntity,
Column,
Entity,
ManyToOne,
PrimaryGeneratedColumn,
} from 'typeorm';
import { BoardStatus } from './board-status.enum';
import { User } from 'src/auth/user.entity';
@Entity()
export class Board extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@Column()
description: string;
@Column()
status: BoardStatus;
// 추가
@ManyToOne((type) => User, (user) => user.boards, { eager: false })
user: User;
}
import { Board } from 'src/boards/board.entity';
import {
BaseEntity,
Column,
Entity,
OneToMany,
PrimaryGeneratedColumn,
Unique,
} from 'typeorm';
@Entity()
@Unique(['username'])
export class User extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@Column()
username: string;
@Column()
password: string;
// 추가
@OneToMany((type) => Board, (board) => board.user, { eager: true })
boards: Board[];
}
각 파라미터는 다음과 같다.
1. Type: 타입 정의
2. InverseSide (접근 경로)
(board) => board.user:
board.user를 통해서 board에서 user를 접근하는 방법을 명시
3. Option
{ eager: true }:
user를 가져올때 board를 가져온다.
// BoardRepository
async createBoard(
createBoardDto: CreateBoardDto,
user: User,
): Promise<Board> {
const { title, description } = createBoardDto;
const board = this.create({
title,
description,
status: BoardStatus.PUBLIC,
user, // board.user 를 통해 접근 가능
});
await this.save(board);
return board;
}
// BoardsService
createBoard(createBoardDto: CreateBoardDto, user: User): Promise<Board> {
return this.boardRepository.createBoard(createBoardDto, user);
}
// BoardsController
@Post()
@UsePipes(ValidationPipe)
createBoard(
@Body() createBoardDto: CreateBoardDto,
@GetUser() user: User, // 유저정보를 받아왔다.
): Promise<Board> {
return this.boardsService.createBoard(createBoardDto, user);
}
이제 게시글을 생성해보면 다음과 같은 쿼리로 처리되는 것을 볼 수 있다.
query: INSERT INTO `board`(`id`, `title`, `description`, `status`, `userId`) VALUES (DEFAULT, ?, ?, ?, ?) -- PARAMETERS: ["new board","new board description","PUBLIC",6]
위에서 마지막에 들어가는 6이라는 데이터는 작성자 유저의 ID값을 의미한다.
기존에 모든 게시글을 가져올때 this.boardRepository.find();를 통해서 모든 게시글을 가져왔다.
이번에는 게시글을 가져오는 요청을 보낸 유저의 게시글만 가져오도록 수정해보자.
createQueryBuilder() 사용해서 검색 조건 추가하기
async getAllBoard(user: User): Promise<Board[]> {
const query = this.boardRepository.createQueryBuilder('board'); // 검색할 객체를 'board'라고 하겠다.
query.where('board.userId = :userId', { userId: user.id }); // 조건 추가.
const boards = await query.getMany();
return boards;
}
// controller
@Delete('/:id')
deleteBoard(
@GetUser() user: User,
@Param('id', ParseIntPipe) id: number,
): Promise<void> {
return this.boardsService.deleteBoard(id, user);
}
// service
async deleteBoard(id: number, user: User): Promise<void> {
const result = await this.boardRepository
.createQueryBuilder()
.delete()
.from(Board)
.where('id = :id and user = :userId', { id, userId: user.id })
.execute();
if (result.affected === 0) {
throw new NotFoundException(`Can't find Board with id ${id}`);
}
}
원래 const result = await this.boardRepository.delete({id, user}); 로 작성하려고 했는데 어째서인지 user에서 에러가 나더라...
왜 때문인지 모르겠는데 다음에 다시 알아보려구 한다.
이에 대해서 알게 되면 따로 포스팅하도록 하자...