SeoMiYoung / CA_nodedotjs_mongodb

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

수정 기능 구현

SeoMiYoung opened this issue · comments

게시물 수정 기능을 구현하는 과정을 살펴봅시다.

🔶 과정

🔸 수정 페이지 만들기

edit.ejs에 수정할 수 있는 페이지를 만들었습니다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link href="/css/main.css" rel="stylesheet"/>
</head>
<body class="grey-bg">
    <%- include('nav.ejs') %>
    <form class="form-box" action="/edit" method="POST">
        <h4>수정하기</h4>
        <input type="hidden" name="id" value="<%= result._id %>">
        <input name="title" value="<%= result.title %>"> 
        <input name="content" value="<%= result.content %>">
        <button type="submit">수정 완료</button>
    </form>
</body>
</html>

🔸 '수정하기'를 클릭하면, 클릭한 글에 대한 수정페이지로 이동 (GET)

특정 글에서 수정을 원하면, 어쩌구/edit/id번호로 페이지를 이동시킵니다.

// server.js 코드
app.get('/edit/:id', async(요청, 응답) => {
    try {
        // collection에 있는 조건에 맞는 가장 첫번째 document만 가져와주세요.
        let result = await db.collection('shopData').findOne({ _id : new ObjectId(요청.params.id)})
    
        if (result == null) {
            응답.status(404).send('url에 해당하는 id없음')
        }
        else {
            응답.render('edit.ejs', {result: result})
        }
    } catch(e) {
        응답.status(404).send('url이 이상해서 에러 발생')
    }
})

🔸 DB의 글을 수정합시다 (POST)

// server.js 코드
// 굳이 PUT쓰고 싶으면, ajax또는 외부 라이브러리 설치해서 쓰면 됨
app.post('/edit', async (요청, 응답) => {
    // user가 입력한 데이터를 출력하기 위해
    console.log(요청.body)

    try {
        if (요청.body.title == '') {
            응답.send('제목을 입력해주세요.')
        }
        else if (요청.body.content == '') {
            응답.send('내용을 입력해주세요.')
        }
        else {
            await db.collection('shopData').updateOne(
                { _id: new ObjectId(요청.body.id) },
                {
                    $set: {
                        title: 요청.body.title,
                        content: 요청.body.content
                    }
                }
            );
        
            // 데이터를 DB에 저장하고 나서, redirect로 다른 페이지 이동
            응답.redirect('/detail/'+ 요청.body.id)
        } 
    } catch(e) {
        // 어떤 에러인지 출력해보고 싶다면?
        console.log(e)
        응답.status(500).send('서버에 에러가 발생했습니다.')
    }
})

[왜 POST를 사용했냐?]

form태그에서는 GET과 POST만 사용할 수 있고, PUT이나 DELETE는 사용할 수 없습니다. PUT같은거 쓰면 좀 더 이쁜 API를 만들 수 있으나, ajax나 외부라이브러리 이런거 가져다가 써야해서 쉽게 가져다가 쓸 수 있는게 아닙니다.. method-override쓰면 될 수도 있습니다.

[updateOne 추가 문법]

  1. $set: 기존값을 덮어쓰기 해줌
  2. $inc: 기존값에 추가 (ex. 숫자 덧셈 뺄셈)
  3. $mul: 기존값에 곱셈
  4. $unset: 기존에 있던 필드를 삭제해줌 (그치만 이것보다는 그냥 빈 문자열에 0을 집어넣거나 하는 경우가 더 편할 수 있으니 알아만 두삼)

[만약에 여러 document수정을 원한다면?]

뭐 여러개의 updateOne을 써도 되는데, 그냥 updateMany를 쓰면 편합니다.
예를 들면, title이 '안녕하세용'으로 되어있는 document들을 다 찾아서 수정을 해줄수도 있고, 아니면 원하면 num같은게 10이상인 document들만 찾아서 전부 수정하는 식으로, $gt, $lt 연산자를 활용해서 조건문을 넣어줄수도 있습니다.
=> 필요하면 그때 그때 찾아서 사용하는게 좋음!

🔶 결과

Animation

🔶 고려해 볼 예외처리

  • 유저가 글의 id를 보내지 않으면?
  • 수정할 글을 보냈는데 글이 비어있으면?
  • 글이 너무 길면?
  • DB에서 수정이 실패하고 에러가 나면?
  • <input type="hidden" name="id" value="<%= result._id %>">
    이렇게 아무리 숨겨도, 사용자 입장에서 개발자도구 같은걸로 조작 가능하기 때문에,
    서버측에서 한번 더 검사해서 걸러주는 작업이 추가로 필요할 듯 하다.