502번째 줄
608번째 줄
624번째 줄
669번째 줄
C : create
R : read
U : update
D : delete
그런데 게시글에 정보를 이것저것 꾸겨넣어놨더니 업데이트를 손을 댈 수가 없는 지경에 와버렸다.
fetchBoard를 하면 볼 수 있는 정보들그래서 도대체 어떻게 해야할까 하다가 엉망진창이였던 구조부터 엎었다.
@UseGuards(GqlAuthAccessGuard)
@Mutation(() => Board)
createBoard(
@CurrentUser() currentUser: ICurrentUser,
@Args('createBoardInput') createBoardInput: CreateBoardInput,
@Args('boardTagsInput') boardTagsInput: BoardTagsInput,
) {
return this.boardService.create({
createBoardInput,
boardTagsInput,
currentUser,
});
}
@InputType()
export class BoardTagsInput {
@Field(() => [String], { nullable: true })
boardTagMenu: string[];
@Field(() => [String], { nullable: true })
boardTagRegion: string[];
@Field(() => [String], { nullable: true })
boardTagMood: string[];
}
@InputType()
export class CreateBoardInput {
@Field(() => String)
boardTitle: string;
@Field(() => String, { nullable: true })
boardSugar: string;
@Field(() => String, { nullable: true })
boardSalt: string;
@Field(() => String)
boardContents: string;
@Field(() => BOARD_SUB_CATEGORY_NAME_ENUM)
subCategoryName: string;
@Field(() => PlaceInput)
place: { PlaceInput: string };
}
DTO는 최대한 한개로 압축해서 처리하기 위해 사용하는 것인데
글 생성에 DTO가 두개가 있다는 것이 뭔가 이상해보인다.
더불어서 이 상태의 create 코드는 Promise.all에 map이 5개나 돌아가는 구조였고
글을 생성하는데 130줄가량이나 되는 문제가 있었다.
그래서 업데이트가 불가능한 것이 말이 안되기에, 고민을 계속 해봤는데
태그를 보면 메뉴,지역,분위기 3개로 나눴는데
유저가 태그를 새로 생성할 수 있는 것이 아니라, 그냥 선택만 할 수 있는 조건이였다.
태그때문에 수정에 에러가 발생하고 있는 것이였는데
어짜피 선택
만 할 수 있다면 굳이 분리를 할 필요가 없다는 것을 자각했다.
그래서 모조리 날려버리고 [tags]의 형태로 받기로 했더니 문제가 있던 것들이 다 풀렸다.
물론 프론트와 대화를 한 후에 api 수정이 이루어졌다. 엄마한테 허락받는 기분
그래서 이러한 형식으로 변하게 되었다.
@InputType()
export class CreateBoardInput {
@Field(() => String)
boardTitle: string;
@Field(() => String)
boardSugar: string;
@Field(() => String)
boardSalt: string;
@Field(() => String)
boardContents: string;
@Field(() => BOARD_SUB_CATEGORY_NAME_ENUM)
subCategoryName: string;
@Field(() => [String])
tags: string[];
@Field(() => PlaceInput)
place: { PlaceInput: string };
}
@UseGuards(GqlAuthAccessGuard)
@Mutation(() => Board)
createBoard(
@CurrentUser() currentUser: ICurrentUser,
@Args('createBoardInput') createBoardInput: CreateBoardInput,
) {
return this.boardService.create({createBoardInput,currentUser})
}
그리고 로직에 대한 변화도 바로 확인을 할 수 있었다.
각 태그별로 반복문이 돌아가던 것을 한개로 합치면서 코드의 복잡도가 한결 나아졌다.
또 명확해지면서 업데이트를 할 수 있는 방향을 잡게 되었다.
일단 업데이트를 제일 쉽게 하는 방법은 아래와 같다.
이렇게 할 경우 어지간한 것은 전부 해결이 된다.
그런데 본문같이 한개의 컬럼으로 이루어져있는 것은 이런 방식으로 하는 것이 맞겠지만
관계가 존재하는 컬럼의 경우에는 비효율적이라고 생각했다.
그래서 이것을 구현하기 위해서 Array.prototype.filter와 includes를 사용하여 차집합을 구했다.
아래는 이렇게 차집합을 구해서 데이터를 추가 및 삭제를 하는 현재 쓰고 있는 코드다.
계속 조회하는 로직이 들어가있어서, 아쉬움이 많은데 어떻게 개선을 할 수 있는지는 조금 더 확인을 해봐야할 것 같다.
ManyToMany인 것을 일부로 풀어서 현재 테이블의 구조가 아래와 같은 형식인데
저렇게 조회를 하지 않고서는 값을 가져오는 것이 불가능한 것 같아서 로직은 저렇게 되어있다.
맨 위부터 순서를 적어보면
이러한 구조로 3개의 테이블의 조인되어있는 테이블들이 수정된다.
async update({ currentUser, boardId, updateBoardInput }) {
const { tags, place, ...inputData } = updateBoardInput;
const board = await this.boardRepository.findOne({
where: { boardId },
relations: ['user'],
});
if (board.user.userId !== currentUser.userId)
throw new UnauthorizedException('해당 글의 작성자가 아닙니다.');
if (place) {
const newPlace = await this.isPlace({ place });
await this.boardRepository.update({ boardId }, { place: newPlace });
}
if (updateBoardInput.boardContents) {
this.imageUpdate({ updateBoardInput, board, boardId });
}
if (tags) {
this.tagUpdate({ board, tags, boardId });
}
const newBoard = {
...board,
...inputData,
};
return await this.boardRepository.save(newBoard);
}
그런데 조금 고민인 것은 조인된 테이블을 추가 및 삭제하는 코드가 상당히 길어서
퍼사드패턴을 사용하여 클래스 내부에 선언을 해놓고 this로 불러오고 있는데 코드가 깔끔해보인다는 장점은 있지만
역시나 내부 로직이 돌아가는 것을 확인하려면 이리저리 왔다갔다 해야한다는 점이 있어서
이 부분이 현명한 선택인 건지, 아쉬운 선택인 것인지 알 길이 없어서 조금 답답하다.
아무튼 업데이트를 못해서 반푼만도 못한 개발자라고 좀 슬퍼하고 있었는데 해결해서 넘 다행이다!
끝!