해결된 질문
23.03.09 13:20 작성
·
393
·
수정됨
0
products.service.ts에서 create 부근에 tag를 저장 하기 전 tag를 미리 조회하는 부분을 구현 중인데 findOne에서 {name: tagname} 을 구현하려고 할 때 다음과 같은 에러가 발생합니다. save에서는 에러가 발생하지 않는데 findOne 조회 부분만 에러가 발생하네요
관련된 코드 같이 보내드립니다.
createProduct.input.ts
import { InputType, Field, Int } from '@nestjs/graphql';
import { Min } from 'class-validator';
import { ProductSaleslocationInput } from 'src/apis/productsSaleslocation/entities/dto/productSaleslocation.input';
@InputType()
export class CreateProductInput {
@Field(() => String)
name: string;
@Field(() => String)
description: string;
@Min(0)
@Field(() => Int)
price: number;
@Field(() => ProductSaleslocationInput)
productSaleslocation: ProductSaleslocationInput;
@Field(() => String)
productCategotyId: string;
@Field(() => [String])
productTags: string[];
}
products.entity.ts
import { Field, Int, ObjectType } from '@nestjs/graphql';
import { ProductCategory } from 'src/apis/productsCategory/entities/productsCategory.entity';
import { ProductTag } from 'src/apis/productsTags/productTags.entity';
import { User } from 'src/apis/users/users.entity';
import {
Column,
DeleteDateColumn,
Entity,
JoinColumn,
JoinTable,
ManyToMany,
ManyToOne,
OneToOne,
PrimaryGeneratedColumn,
} from 'typeorm';
import { ProductSaleslocation } from '../../productsSaleslocation/entities/productsSaleslocation.entity';
@Entity()
@ObjectType()
export class Product {
@PrimaryGeneratedColumn('uuid')
@Field(() => String)
id: string;
@Field(() => String)
@Column()
name: string;
@Field(() => String)
@Column()
description: string;
@Field(() => Int)
@Column()
price: number;
@Field(() => Boolean)
@Column({ default: false })
isSoldout: boolean;
@DeleteDateColumn()
deletedAt: Date;
@Field(() => ProductSaleslocation)
@JoinColumn()
@OneToOne(() => ProductSaleslocation)
productSaleslocation: ProductSaleslocation;
@Field(() => ProductCategory)
@ManyToOne(() => ProductCategory)
productCategory: ProductCategory;
@Field(() => User)
@ManyToOne(() => User)
user: User;
@JoinTable()
@ManyToMany(() => ProductTag, (productTags) => productTags.products)
@Field(() => [ProductTag])
productTags: ProductTag[];
}
productTags.entity.ts
import { Field, ObjectType } from '@nestjs/graphql';
import { Column, Entity, ManyToMany, PrimaryGeneratedColumn } from 'typeorm';
import { Product } from '../products/entities/products.entity';
@Entity()
@ObjectType()
export class ProductTag {
@Field(() => String)
@PrimaryGeneratedColumn('uuid')
id: string;
@Column()
@Field(() => String)
name: string;
@Field(() => [Product])
@ManyToMany(() => Product, (products) => products.productTags)
products: Product[];
}
products.service.ts
import { Product } from './entities/products.entity';
import { Injectable, UnprocessableEntityException } from '@nestjs/common';
import { Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { ProductSaleslocation } from '../productsSaleslocation/entities/productsSaleslocation.entity';
import { ProductTag } from '../productsTags/productTags.entity';
@Injectable()
export class ProductService {
constructor(
@InjectRepository(Product)
private readonly productRepository: Repository<Product>,
@InjectRepository(ProductSaleslocation)
private readonly productSaleslocationRepository: Repository<ProductSaleslocation>,
@InjectRepository(ProductTag)
private readonly productTagRepository: Repository<ProductTag>,
) {}
async findAll() {
return await this.productRepository.find({
relations: ['productSaleslocation', 'productCategory', 'productTags'],
});
}
async findOne({ productId }) {
return await this.productRepository.findOne({
where: { id: productId },
relations: ['productSaleslocation', 'productCategory', 'productTags'],
});
}
async create({ createProductInput }) {
// 1. 상품만 등록하는 경우
// const result = await this.productRepository.save({
// ...createProductInput,
// // 하나 하나 직접 나열하는 방식
// // name: createProductInput.name,
// // description: createProductInput.description,
// // price: createProductInput.price,
// });
// 2. 상품과 상품거래 위치 같이 등록
const { productSaleslocation, productCategotyId, productTag, ...product } =
createProductInput;
const result = await this.productSaleslocationRepository.save({
...productSaleslocation,
});
// productTag // ["#electronics, #computer"]
const result2 = []; // [{name: ..., id: ...}]
for (let i = 0; i < productTags.length; i++) {
const tagName = productTags[i].replace('#', '');
// check the tags that has already registered
const checkTag = await this.productTagRepository.findOne({
name: tagName,
});
// if the tags has been existed
if (checkTag) {
result2.push(checkTag);
// if the tags hasn't been existed
} else {
const newTag = await this.productTagRepository.save({ name: tagName });
result2.push(newTag);
}
}
const result3 = await this.productRepository.save({
...product,
productSaleslocation: result, // result 통째로 넣기 vs id만 넣기
productCategory: { id: productCategotyId },
productTags: result2,
});
return result3;
}
async update({ productId, updateProductInput }) {
const myProduct = await this.productRepository.findOne({
where: { id: productId },
});
const newProduct = {
...myProduct,
id: productId,
...updateProductInput,
};
return await this.productRepository.save(newProduct);
}
async checkSoldOut({ productId }) {
const product = await this.productRepository.findOne({
where: { id: productId },
});
if (product.isSoldout) {
throw new UnprocessableEntityException('Sold out');
}
// if(product.isSoldout) {
// throw new HttpException('이미 판매 완료 된 상품입니다.', HttpStatus.UNPROCESSABLE_ENTITY)
// }
}
async delete({ productId }) {
// 1. 실제 삭제
// const result = await this.productRepository.delete({ id: productId });
// return result.affected ? true : false
// 2. 소프트 삭제(직접 구현) - isDeleted
// this.productRepository.update({ id: productId }, { isDeleted: true });
// 3. 소프트 삭제(직접 구현) - deletedAt
// this.productRepository.update({ id: productId }, { deletedAt: new Date() });
// 4. 소프트 삭제(TypeORM 제공) - softRemove - id로만 삭제 가능
// this.productRepository.softRemove({ id: productId });
// 4 . 소프트 삭제(TypeORM 제공) - softDelete
const result = await this.productRepository.softDelete({ id: productId });
return result.affected ? true : false;
}
}
내용 확인 부탁드립니다.
2023. 03. 09. 16:11
typeorm 최신 버전하고 강의 버전하고 문법 차이가 있어요