- 엔티티 수정
/**
* 게시글은 1명의 사용자를 가진다.
* 사용자는 게시글 여러개를 가진다.
* users 모델에서 posts모델을 표현하는 속성이 posts다.
*/
@ManyToOne(()=>UsersModel, (user)=> user.posts, {
nullable: false,
})
author: UsersModel;
/**
* 사용자는 여러개의 post를 가진다.
* (연동할모델, 반환 모델)
* 포스트모델의 어떤 속성하고 연동인지? post.author
*/
@OneToMany(()=> PostsModel, (post) => post.author)
posts : PostsModel[];
* 오류
- 원인 : author는 더이상 string이 아니라, user 객체이기 때문.
- 해결 : authorId로 인자를 바꿈
- 예시 : authorId가 1 -> 1번 유저와 연동됨.
* 오류2
QueryFailedError: column "authorId" of relation "posts_model" contains null values
- 원인 : author는 이제 user 타입인데, 기존의 varchar로 되있음. 기존 data가 어디로 들어갈지 모르기때문임
- 해결1 : migration 로직 작성
- 해결2 : post-data 폴더 삭제후, docker-compose up으로 재실행
- 결과 : 다 쪽에 FK가 하나 생기고, user의 id를 가르키고 있음.
- 1쪽에는 아무 변화가 없음.
* 문제
- post를 가져올때, user(author)가 안보임
- 원인 : 서비스는 PostModel만 신경씀 (default)
export class PostsService {
constructor(
@InjectRepository(PostsModel)
private readonly postsRepository: Repository<PostsModel>) {
}
- 해결 : typeorm의 relation도 가져오라고 수정.
async getAllPosts(){
return await this.postsRepository.find({
relations:['author'],
});
}
- 작동원리 : post는 author_id=1만 가지고 있음 -> 이걸 가지고 select from user where id =1로 user정보를 가져오는 것임.
- gpt
네, 이 코드는 TypeORM에서 엔티티 간의 관계를 정의하는 부분입니다. 구체적으로 Many-to-One 관계를 설정하고 있습니다. 각 부분을 상세히 설명해 드리겠습니다.
/**
* 사용자는 게시글 여러개를 가진다.
*/
@ManyToOne(() => UsersModel, (user) => user.posts)
author: UsersModel;
- 주석 설명:
- 이 주석은 관계의 본질을 설명합니다: "사용자는 게시글 여러 개를 가진다."
- 이는 One-to-Many 관계의 반대 측면을 나타냅니다.
@ManyToOne
데코레이터:- 이 데코레이터는 "많은" 쪽(현재 엔티티, 아마도 PostsModel)에서 "하나"의 쪽(UsersModel)으로의 관계를 정의합니다.
- 즉, 여러 게시글이 하나의 사용자에 속할 수 있음을 의미합니다.
- 데코레이터 인자:
- 첫 번째 인자
() => UsersModel
:- 관계의 대상 엔티티를 지정합니다. 여기서는 UsersModel입니다.
- 함수 형태로 제공되어 순환 의존성 문제를 방지합니다.
- 두 번째 인자
(user) => user.posts
:- 이는 역 관계를 정의합니다.
- UsersModel에서 이 관계에 접근할 때 사용할 속성 이름을 지정합니다.
- 즉, UsersModel에는
posts
속성이 있어야 하며, 이를 통해 사용자의 모든 게시글에 접근할 수 있습니다.
- 첫 번째 인자
author: string;
:- 이 부분은 TypeScript 타입 정의입니다.
- 하지만 실제로는
string
타입이 아닐 가능성이 높습니다. UsersModel의 인스턴스나 사용자 ID(보통 number 타입)가 될 가능성이 더 높습니다.
이 관계 설정을 시각화한 다이어그램을 제공하겠습니다:
erDiagram
POSTS ||--o{ USERS : "belongs to"
POSTS {
int id
string title
string content
int authorId
}
USERS {
int id
string name
string email
}
note on POSTS {
authorId is a foreign key
referencing USERS.id
}
이 다이어그램은 다음을 보여줍니다:
- 하나의 USER는 여러 개의 POST를 가질 수 있습니다(One-to-Many).
- 각 POST는 하나의 USER에 속합니다(Many-to-One).
- POSTS 테이블의
authorId
는 USERS 테이블의id
를 참조하는 외래 키입니다.
실제 데이터베이스에서 이 관계는 다음과 같은 SQL 쿼리로 표현될 수 있습니다:
CREATE TABLE "users" (
"id" SERIAL PRIMARY KEY,
"name" VARCHAR NOT NULL,
"email" VARCHAR NOT NULL
);
CREATE TABLE "posts" (
"id" SERIAL PRIMARY KEY,
"title" VARCHAR NOT NULL,
"content" TEXT,
"authorId" INTEGER,
FOREIGN KEY ("authorId") REFERENCES "users" ("id")
);
이 설정의 주요 이점은 다음과 같습니다:
- 데이터 무결성: 외래 키 제약 조건으로 인해 존재하지 않는 사용자에 게시글을 할당할 수 없습니다.
- 효율적인 쿼리: 사용자의 모든 게시글이나 게시글의 작성자를 쉽게 조회할 수 있습니다.
- 관계의 명확성: 코드 레벨에서 엔티티 간의 관계가 명확히 표현됩니다.
마지막으로, author: string;
부분은 아마도 다음과 같이 수정되어야 할 것 같습니다:
@ManyToOne(() => UsersModel, (user) => user.posts)
author: UsersModel;
이렇게 하면 author
속성의 타입이 UsersModel
이 되어, TypeORM이 올바르게 관계를 처리할 수 있습니다.
'JS > Nest.js' 카테고리의 다른 글
[Nest] base64 토큰 인증 구현 (0) | 2024.09.18 |
---|---|
[Nest] JWT 토큰발급 구현, 외부 모듈 import-export 하는법 (0) | 2024.09.18 |
[Nest] typeorm 설정, 리포지토리 설정방법 (0) | 2024.09.18 |
[Nest] enum => 값 제한 하기 (0) | 2024.09.18 |
[Nest] CRUD 구현, body 받는법 (0) | 2024.09.17 |