재료를 배열 안 객체로 수정해 ingredientUnit 삭제
@Column('json')
ingredient: { item: string; unit: string }[];
요리스텝도 배열 안 객체로 생성
@Column('json')
step: { stepNum: number; des: string; imgUrl: string }[];
지금까지 생성한 유저모델과 리뷰 모델과 관계설정
@ManyToMany(() => User, (user) => user.recipes)
@JoinColumn()
user: User;
@ManyToOne(() => Review)
review: Review;
dto수정
> 배열 안에 들어가는 객체를 클래스로 만들어 유효성 검사 따로 들어가고 재료랑 스텝에 타입에 클래스로 만든 것 넣기
class IngredientDto {
@IsString()
item: string;
@IsString()
unit: string;
}
class stepDto {
@IsNumber()
stepNum: number;
@IsString()
des: string;
@IsString()
imgUrl: string;
}
@IsArray()
@ValidateNested({ each: true })
@Type(() => IngredientDto)
ingredient: { item: string; unit: string }[];
@IsArray()
@ValidateNested({ each: true })
@Type(() => stepDto)
step: { stepNum: number; des: string; imgUrl: string }[];
리뷰모델
<review.entity.ts>
import { User } from 'src/auth/user.entity';
import { Recipe } from 'src/recipe/recipe.entity';
import {
BaseEntity,
Column,
CreateDateColumn,
DeleteDateColumn,
Entity,
JoinColumn,
ManyToOne,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
@Entity()
export class Review extends BaseEntity {
@PrimaryGeneratedColumn()
reviewId: number;
@Column({ type: 'int' })
star: number;
@Column()
comment: string;
@CreateDateColumn({ type: 'timestamp' })
createdAt: Date;
@UpdateDateColumn({ type: 'timestamp' })
updatedAt: Date;
@DeleteDateColumn({ type: 'timestamp' })
deletedAt: Date;
@ManyToOne(() => User)
@JoinColumn({ name: 'id' })
user: User;
@ManyToOne(() => Recipe)
@JoinColumn({ name: 'recipeId' })
recipe: Recipe;
}
date의 경우 timestamp를 명시해주는 이유 - date type의 컬럼은 datetime형태로 저장됨
createDateColumn, updateDateColumn 키는 repositoy에 연계되어 지정하지 않더라도 생성, 업데이트 시 자동으로 생성됨
deleteDateColumn은 softdelete 할 경우 사용됨 / 실제 find할 경우 불러오지 않게됨
<review.dto.ts>
import { IsDate, IsNumber, IsString } from 'class-validator';
export class CreateReviewDto {
@IsNumber()
star: number;
@IsString()
comment: string;
}
<update-review.dto>
import { PartialType } from '@nestjs/mapped-types';
import { CreateReviewDto } from './create-review.dto';
export class UpdateReviewDto extends PartialType(CreateReviewDto) {}
<review.repositoy.ts>
import { InjectRepository } from '@nestjs/typeorm';
import { Review } from './review.entity';
import { DataSource, Repository } from 'typeorm';
import { CreateReviewDto } from './dto/create-review.dto';
export class ReviewRepository extends Repository<Review> {
constructor(@InjectRepository(Review) private dataSource: DataSource) {
super(Review, dataSource.manager);
}
async createReview(createReviewDto: CreateReviewDto): Promise<Review> {
const { star, comment } = createReviewDto;
const review = this.create({ star, comment });
await this.save(review);
return review;
}
}
<review.service.ts>
import { Injectable, NotFoundException } from '@nestjs/common';
import { ReviewRepository } from './review.repositoy';
import { Review } from './review.entity';
import { CreateReviewDto } from './dto/create-review.dto';
import { UpdateReviewDto } from './dto/update-review.dto';
@Injectable()
export class ReviewService {
constructor(private reviewRepositoty: ReviewRepository) {}
async getAllReview(): Promise<Review[]> {
return this.reviewRepositoty.find();
}
createReview(createReviewDto: CreateReviewDto): Promise<Review> {
return this.reviewRepositoty.createReview(createReviewDto);
}
async getReviewById(reviewId: number): Promise<Review> {
const found = await this.reviewRepositoty.findOneBy({ reviewId });
if (!found) {
throw new NotFoundException(
`reviewId가 ${reviewId}인 리뷰를 찾을 수 없습니다.`,
);
}
return found;
}
async deleteReview(reviewId: number): Promise<void> {
const result = await this.reviewRepositoty.delete(reviewId);
if (result.affected === 0) {
throw new NotFoundException(`can't find reviewId ${reviewId}`);
}
}
async updateReview(
reviewId: number,
updateReviewDto: UpdateReviewDto,
): Promise<Review> {
const found = await this.reviewRepositoty.findOne({
where: { reviewId },
});
if (!found) {
throw new NotFoundException(
`reviewId가 ${reviewId}인 리뷰를 찾을 수 없습니다.`,
);
}
await this.reviewRepositoty.update(reviewId, updateReviewDto);
const updateReview = await this.reviewRepositoty.findOne({
where: { reviewId },
});
return updateReview;
}
}
<review.controller.ts>
import {
Body,
Controller,
Delete,
Get,
Param,
ParseIntPipe,
Patch,
Post,
} from '@nestjs/common';
import { ReviewService } from './review.service';
import { Review } from './review.entity';
import { CreateReviewDto } from './dto/create-review.dto';
import { create } from 'domain';
import { UpdateReviewDto } from './dto/update-review.dto';
@Controller('review')
export class ReviewController {
constructor(private reviewService: ReviewService) {}
@Get('/')
getAllTask(): Promise<Review[]> {
return this.reviewService.getAllReview();
}
@Post('/insert')
createReview(@Body() createReviewDto: CreateReviewDto): Promise<Review> {
return this.reviewService.createReview(createReviewDto);
}
@Get('/:reviewId')
getReviewById(@Param('reviewId') reviewId: number): Promise<Review> {
return this.reviewService.getReviewById(reviewId);
}
@Patch('/:reviewId')
updateReview(
@Param('reviewId') reviewId: number,
@Body() reviewData: UpdateReviewDto,
): Promise<Review> {
return this.reviewService.updateReview(reviewId, reviewData);
}
@Delete('/:reviewId')
deleteReview(@Param('reviewId', ParseIntPipe) reviewId): Promise<void> {
return this.reviewService.deleteReview(reviewId);
}
}
#엘리스트랙 #엘리스트랙후기 #리액트네이티브강좌 #온라인코딩부트캠프 #온라인코딩학원 #프론트엔드학원 #개발자국비지원 #개발자부트캠프 #국비지원부트캠프 #프론트엔드국비지원 #React #Styledcomponent #React Router Dom #Redux #Typescript #Javascript
'프로젝트 개발' 카테고리의 다른 글
23.12.25(전체적으로 수정, 파일 모델 추가) (1) | 2023.12.25 |
---|---|
23.12.22 (관계 설정 후 활용) (1) | 2023.12.22 |
23.12.18 (유저모델 수정, 레시피모델 추가) (1) | 2023.12.18 |
23.12.14 (nest 공부 - 파이프, 유저관련) (0) | 2023.12.14 |
23.12.13 (nest.js 공부-모듈+crud) (0) | 2023.12.13 |