-
Notifications
You must be signed in to change notification settings - Fork 4
[Feat] 질문지 조회 기능에 Pagination 구현 #254
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d7d4320
52c4476
ea5d5f3
4627440
90cb1fe
5fffd3b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ import { QuestionList } from "./question-list.entity"; | |
| import { Question } from "./question.entity"; | ||
| import { Category } from "./category.entity"; | ||
| import { User } from "@/user/user.entity"; | ||
| import { PaginateQuery } from "nestjs-paginate"; | ||
|
|
||
| @Injectable() | ||
| export class QuestionListRepository { | ||
|
|
@@ -18,9 +19,10 @@ export class QuestionListRepository { | |
| } | ||
|
|
||
| findPublicQuestionLists() { | ||
| return this.dataSource.getRepository(QuestionList).find({ | ||
| where: { isPublic: true }, | ||
| }); | ||
| return this.dataSource | ||
| .getRepository(QuestionList) | ||
| .createQueryBuilder("question_list") | ||
| .where("question_list.is_public = :isPublic", { isPublic: true }); | ||
| } | ||
|
|
||
| async getCategoryIdByName(categoryName: string) { | ||
|
|
@@ -33,13 +35,12 @@ export class QuestionListRepository { | |
| } | ||
|
|
||
| findPublicQuestionListsByCategoryId(categoryId: number) { | ||
| return this.dataSource.getRepository(QuestionList).find({ | ||
| where: { | ||
| isPublic: true, | ||
| categories: { id: categoryId }, | ||
| }, | ||
| relations: ["categories"], | ||
| }); | ||
| return this.dataSource | ||
| .getRepository(QuestionList) | ||
| .createQueryBuilder("question_list") | ||
| .innerJoin("question_list.categories", "category") | ||
| .where("question_list.is_public = :isPublic", { isPublic: true }) | ||
| .andWhere("category.id = :categoryId", { categoryId }); | ||
|
Comment on lines
-36
to
+43
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 깔끔하게 리팩토링 된 것 같아서 좋습니다! 쿼리빌더 이제 잘 활용하시는 것 같아서� 같은 백엔드 개발자로써 뿌듯하네용 ㅎㅎㅎ |
||
| } | ||
|
|
||
| async findCategoryNamesByQuestionListId(questionListId: number) { | ||
|
|
@@ -66,9 +67,11 @@ export class QuestionListRepository { | |
| } | ||
|
|
||
| getContentsByQuestionListId(questionListId: number) { | ||
| return this.dataSource.getRepository(Question).find({ | ||
| where: { questionListId }, | ||
| }); | ||
| return this.dataSource | ||
| .getRepository(Question) | ||
| .createQueryBuilder("question") | ||
| .where("question.question_list_id = :questionListId", { questionListId }) | ||
| .getMany(); | ||
| } | ||
|
|
||
| async getUsernameById(userId: number) { | ||
|
|
@@ -80,9 +83,10 @@ export class QuestionListRepository { | |
| } | ||
|
|
||
| getQuestionListsByUserId(userId: number) { | ||
| return this.dataSource.getRepository(QuestionList).find({ | ||
| where: { userId }, | ||
| }); | ||
| return this.dataSource | ||
| .getRepository(QuestionList) | ||
| .createQueryBuilder("question_list") | ||
| .where("question_list.userId = :userId", { userId }); | ||
| } | ||
|
|
||
| getQuestionCountByQuestionListId(questionListId: number) { | ||
|
|
@@ -109,9 +113,11 @@ export class QuestionListRepository { | |
| } | ||
|
|
||
| getScrappedQuestionListsByUser(user: User) { | ||
| return this.dataSource.getRepository(QuestionList).find({ | ||
| where: { scrappedByUsers: user }, | ||
| }); | ||
| return this.dataSource | ||
| .getRepository(QuestionList) | ||
| .createQueryBuilder("question_list") | ||
| .innerJoin("question_list.scrappedByUsers", "user") | ||
| .where("user.id = :userId", { userId: user.id }); | ||
| } | ||
|
|
||
| unscrapQuestionList(questionListId: number, userId: number) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ import { MyQuestionListDto } from "./dto/my-question-list.dto"; | |
| import { Question } from "./question.entity"; | ||
| import { Transactional } from "typeorm-transactional"; | ||
| import { QuestionList } from "@/question-list/question-list.entity"; | ||
| import { paginate, PaginateQuery } from "nestjs-paginate"; | ||
|
|
||
| @Injectable() | ||
| export class QuestionListService { | ||
|
|
@@ -16,12 +17,16 @@ export class QuestionListService { | |
| private readonly userRepository: UserRepository | ||
| ) {} | ||
|
|
||
| async getAllQuestionLists() { | ||
| async getAllQuestionLists(query: PaginateQuery) { | ||
| const allQuestionLists: GetAllQuestionListDto[] = []; | ||
|
|
||
| const publicQuestionLists = await this.questionListRepository.findPublicQuestionLists(); | ||
| const result = await paginate(query, publicQuestionLists, { | ||
| sortableColumns: ["usage"], | ||
| defaultSortBy: [["usage", "DESC"]], | ||
| }); | ||
|
Comment on lines
+24
to
+27
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sort 기준과 기본 sort 기준까지.. 괜찮네요! 이부분 나중에 enum으로 리팩토링 해보시겠다고 하셨는데 이쪽에서도 활용해보시면 괜찮을 것 같네요! |
||
|
|
||
| for (const publicQuestionList of publicQuestionLists) { | ||
| for (const publicQuestionList of result.data) { | ||
| const { id, title, usage } = publicQuestionList; | ||
| const categoryNames: string[] = | ||
| await this.questionListRepository.findCategoryNamesByQuestionListId(id); | ||
|
|
@@ -38,22 +43,26 @@ export class QuestionListService { | |
| }; | ||
| allQuestionLists.push(questionList); | ||
| } | ||
| return allQuestionLists; | ||
| return { allQuestionLists, meta: result.meta }; | ||
| } | ||
|
|
||
| async getAllQuestionListsByCategoryName(categoryName: string) { | ||
| async getAllQuestionListsByCategoryName(categoryName: string, query: PaginateQuery) { | ||
| const allQuestionLists: GetAllQuestionListDto[] = []; | ||
|
|
||
| const categoryId = await this.questionListRepository.getCategoryIdByName(categoryName); | ||
|
|
||
| if (!categoryId) { | ||
| return []; | ||
| return {}; | ||
| } | ||
|
|
||
| const publicQuestionLists = | ||
| await this.questionListRepository.findPublicQuestionListsByCategoryId(categoryId); | ||
| const result = await paginate(query, publicQuestionLists, { | ||
| sortableColumns: ["usage"], | ||
| defaultSortBy: [["usage", "DESC"]], | ||
| }); | ||
|
|
||
| for (const publicQuestionList of publicQuestionLists) { | ||
| for (const publicQuestionList of result.data) { | ||
| const { id, title, usage } = publicQuestionList; | ||
| const categoryNames: string[] = | ||
| await this.questionListRepository.findCategoryNamesByQuestionListId(id); | ||
|
|
@@ -70,7 +79,7 @@ export class QuestionListService { | |
| }; | ||
| allQuestionLists.push(questionList); | ||
| } | ||
| return allQuestionLists; | ||
| return { allQuestionLists, meta: result.meta }; | ||
| } | ||
|
|
||
| // 질문 생성 메서드 | ||
|
|
@@ -107,7 +116,10 @@ export class QuestionListService { | |
|
|
||
| async getQuestionListContents(questionListId: number) { | ||
| const questionList = await this.questionListRepository.getQuestionListById(questionListId); | ||
| const { id, title, usage, userId } = questionList; | ||
| const { id, title, usage, isPublic, userId } = questionList; | ||
| if (!isPublic) { | ||
| throw new Error("This is private question list."); | ||
| } | ||
|
|
||
| const contents = | ||
| await this.questionListRepository.getContentsByQuestionListId(questionListId); | ||
|
|
@@ -116,7 +128,6 @@ export class QuestionListService { | |
| await this.questionListRepository.findCategoryNamesByQuestionListId(questionListId); | ||
|
|
||
| const username = await this.questionListRepository.getUsernameById(userId); | ||
|
|
||
| const questionListContents: QuestionListContentsDto = { | ||
| id, | ||
| title, | ||
|
|
@@ -129,28 +140,29 @@ export class QuestionListService { | |
| return questionListContents; | ||
| } | ||
|
|
||
| async getMyQuestionLists(userId: number) { | ||
| async getMyQuestionLists(userId: number, query: PaginateQuery) { | ||
| const questionLists = await this.questionListRepository.getQuestionListsByUserId(userId); | ||
| const result = await paginate(query, questionLists, { | ||
| sortableColumns: ["usage"], | ||
| defaultSortBy: [["usage", "DESC"]], | ||
| }); | ||
|
|
||
| const myQuestionLists: MyQuestionListDto[] = []; | ||
| for (const myQuestionList of questionLists) { | ||
| for (const myQuestionList of result.data) { | ||
| const { id, title, isPublic, usage } = myQuestionList; | ||
| const categoryNames: string[] = | ||
| await this.questionListRepository.findCategoryNamesByQuestionListId(id); | ||
|
|
||
| const contents = await this.questionListRepository.getContentsByQuestionListId(id); | ||
|
|
||
| const questionList: MyQuestionListDto = { | ||
| id, | ||
| title, | ||
| contents, | ||
| categoryNames, | ||
| isPublic, | ||
| usage, | ||
| }; | ||
| myQuestionLists.push(questionList); | ||
| } | ||
| return myQuestionLists; | ||
| return { myQuestionLists, meta: result.meta }; | ||
| } | ||
|
|
||
| async findCategoriesByNames(categoryNames: string[]) { | ||
|
|
@@ -163,9 +175,15 @@ export class QuestionListService { | |
| return categories; | ||
| } | ||
|
|
||
| async getScrappedQuestionLists(userId: number) { | ||
| async getScrappedQuestionLists(userId: number, query: PaginateQuery) { | ||
| const user = await this.userRepository.getUserByUserId(userId); | ||
| return await this.questionListRepository.getScrappedQuestionListsByUser(user); | ||
| const scrappedQuestionLists = | ||
| await this.questionListRepository.getScrappedQuestionListsByUser(user); | ||
| const result = await paginate(query, scrappedQuestionLists, { | ||
| sortableColumns: ["usage"], | ||
| defaultSortBy: [["usage", "DESC"]], | ||
| }); | ||
| return { scrappedQuestionLists: result.data, meta: result.meta }; | ||
| } | ||
|
|
||
| async scrapQuestionList(questionListId: number, userId: number) { | ||
|
|
@@ -176,13 +194,16 @@ export class QuestionListService { | |
| if (!questionList) throw new Error("Question list not found."); | ||
|
|
||
| // 스크랩하려는 질문지가 내가 만든 질문지인지 확인 | ||
| const myQuestionLists = await this.questionListRepository.getQuestionListsByUserId(userId); | ||
| const myQuestionLists = await this.questionListRepository | ||
| .getQuestionListsByUserId(userId) | ||
| .getMany(); | ||
| const isMyQuestionList = myQuestionLists.some((list) => list.id === questionListId); | ||
| if (isMyQuestionList) throw new Error("Can't scrap my question list."); | ||
|
|
||
| // 스크랩하려는 질문지가 이미 스크랩한 질문지인지 확인 | ||
| const alreadyScrappedQuestionLists = | ||
| await this.questionListRepository.getScrappedQuestionListsByUser(user); | ||
| const alreadyScrappedQuestionLists = await this.questionListRepository | ||
| .getScrappedQuestionListsByUser(user) | ||
| .getMany(); | ||
| const isAlreadyScrapped = alreadyScrappedQuestionLists.some( | ||
| (list) => list.id === questionListId | ||
| ); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 코드 보면서 느끼는건데, ORM 쓰길 엄청 잘했다고 생각듭니다 ㅋㅋ 코드가 엄청 깔끔하네요