글 작성자: 망고좋아
반응형

🎯 회원과 게시글의 연동

📝 PostSchema 수정

author: {
    type: Schema.Types.ObjectId,
    ref: 'User',
    required: true,
},
  • PostSchema에 author 추가
  • populate를 사용하기 위해 ObjectID 사용
  • ref를 유저 모델의 이름인 'User'로 선언

 

📝 게시글 등록 요청 수정

const author = await User.find({
  shortId: req.user.shortId,
});
if (!author) {
  throw new Error("No User");
}

await Post.create({
  title,
  content,
  author,
});
  • req.user에는 strategy에서 최소한의 정보로 저장한 shortId, email, username만 가지고 있다.
  • Post 생성 시 user의 ObjectID를 전달해야 하는데, 이를 위해 User에서 shortId로 회원을 검색하여 한번 더 검증한다.
  • type: ObjectID로 선언한 필드에 객체가 주어지면 자동으로 ObjectID 사용한다.

 

📝 게시글에 작성자 연동

//--- ./routes/posts.js ---
router.get('/', ... {
    ...
    const posts = await Post
        .find({})
        .sort({ createdAt: -1 })
    .skip(perPage * (page - 1))
    .limit(perPage),
        .populate('author'); // ***********
res.render('posts/list', { posts });

//--- ./views/posts/list.pug ---
...
    td post.author.name // 사용자 이름 추가
  • 게시글 find시 populate를 추가하여 ObjectID로 저장된 author를 각 게시글에 주입
  • 사용 시 post.author.{field}로 사용 가능

 

📝 게시글 수정, 삭제 시 유저 확인

const post = await Post.find({
    shortId,
}).populate('author');

if (post.author.shortId !== req.user.shortId) {
    throw new Error('Not Authorized');
}
  • 게시글 수정, 삭제 시 작성자를 populate 하여 로그인된 사용자의 shortId와 일치하는지 확인

 

📝 작성자 게시글 모아 보기 기능 구현

  • 기본적으로 MongoDB는 Document 검색 시, 전체 문서를 하나씩 확인한다.
    • 하나씩 확인하기 때문에 매우 비효율적인 검색을 수행한다.
    • 데이터가 많아질 경우 속도 저하의 가장 큰 원인이 된다.

 

📕 Index

  • MongoDB는 검색을 위해 Document를 정렬하여 저장하는 기능을 제공한다.
  • Index를 설정하면 주어진 쿼리를 효율적으로 수행하여 성능을 향상할 수 있다

 

📕 author에 index 설정하기

author: {
    type: Schema.Types.ObjectId,
    ref: 'User',
    required: true,
    index: true,
},
  • PostSchema의 author 속성에 index: true 옵션을 사용하면 mongoose가 자동으로 MongoDB에 인덱스를 생성해 준다.
  • 이미 데이터가 많은 상태에서 인덱스를 추가할 시 작업 시간이 길어져, MongoDB가 응답하지 않을 수 있다. → 예상되는 인덱스를 미리 추가하는 것이 좋다.

 

📕 회원 게시글 라우팅 추가하기

//--- ./routes/users.js ---
...
router.get('/:shortId/posts', ... => {
    ...
    const { shortId } = req.params;
    const user = await User.find({ shortId });
    const posts = await Post
        .find({ author: user })
        .populate('author');
    res.render('posts/list', { posts, user });
});
...
  • RESTful 한 구성을 위해, 회원 → 게시글의 경로를 /users/{userId}/posts로 구성
  • 게시글 목록 view는 기존에 작성한 posts/list.pug를 재활용

 

📕 게시글 목록 화면 수정

h2= user ? `${user.name}의 게시글`: "전체 게시글"
...
td: a(href=`/users/${post.author.shortId}`)
= post.author.name
  • 게시글 목록 화면을 재활용하기 위해 수정
  • 유저의 게시글인 경우 "###의 게시글"이라는 제목 사용
  • 게시글의 사용자 이름에 유저의 게시글 link 추가
반응형

'프로그래밍 > Node.js' 카테고리의 다른 글

[Node.js] JWT란?  (0) 2021.12.15
[Node.js] CSR로 댓글 기능 구현하기  (0) 2021.12.13
[Node.js] Session Store 사용하기  (0) 2021.12.13
[Node.js] Passport.js와 로그인  (0) 2021.12.13
[Node.js] 회원가입 구현하기  (0) 2021.12.13