home강의 홈으로
Section 5. MySQL 활용 웹사이트 만들기
Lesson 3. 좋아요와 댓글 달기

1. 좋아요 증감 구현

A. 상세페이지

views/detail.hbs

<h1> {{ biz.icon }} {{ biz.business_name }} </h1> <table> <thead> <tr> <th colspan="2"> 업소 정보 </th> </tr> </thead> <tbody> <tr> <td>섹션</td> <td>{{ biz.section_name }} ({{ biz.floor }}층)</td> </tr> <tr> <td>현재 상태</td> <td>{{ biz.status_kor }}</td> </tr> <tr> <td>배달 가능</td> <td> {{#if biz.can_takeout}} ✔️ {{^}} ❌ {{/if}} </td> </tr> </tbody> </table> <br><br><br> <h2>📋 메뉴</h2> <table> <thead> <tr> <th>메뉴명</th> <th>가격</th> <th>칼로리</th> <th>좋아요</th> </tr> </thead> <tbody> {{#each menus}} <tr> <td>{{ menu_name }}</td> <td>{{ price }}</td> <td>{{ kilocalories }}</td> <td> <span>{{ likes }}</span> <button class="small" onclick="putLike({{ menu_id }}, 1)">+</button> <button class="small" onclick="putLike({{ menu_id }}, -1)">-</button> </td> </tr> {{/each}} </tbody> </table> <br><br><br> <h2>⭐ 평점</h2> <table> <thead> <tr> <th>평점</th> <th>코멘트</th> <th colspan="2">일시</th> </tr> </thead> <tbody> {{#each ratings}} <tr> <td>{{ stars }}</td> <td>{{ comment }}</td> <td>{{ created_fmt }}</td> <td> <button onclick="removeRating({{ rating_id }})">삭제</button> </td> </tr> {{/each}} </tbody> </table> <br> <select id="stars"> <option value="5">5점</option> <option value="4">4점</option> <option value="3">3점</option> <option value="2">2점</option> <option value="1">1점</option> </select> <input id="comment" type="text"> <button onclick="addRating()">올리기</button> <br><br><br> <a href="/biz-simple?section="> ◀️ 업소 목록으로 돌아가기️ </a> <script> function putLike (menu_id, like) { fetch(`/menus/${menu_id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ like: like }) }).then((response) => response.json()).then( (data) => { if (data[0].affectedRows === 1) { location.reload() } else { alert('오류가 발생했습니다.') } } ) } function addRating () { fetch(`/ratings`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ business_id: {{ biz.business_id }}, stars: document.getElementById('stars').value, comment: document.getElementById('comment').value, }) }).then((response) => response.json()).then( (data) => { console.log(data[0]) if (data[0].affectedRows === 1) { location.reload() } else { alert('오류가 발생했습니다.') } } ) } function removeRating (rating_id) { if (!confirm('이 평점을 삭제하시겠습니까?')) return fetch(`/ratings/${rating_id}`, { method: 'DELETE' }).then((response) => response.json()).then( (data) => { console.log(data[0]) if (data[0].affectedRows === 1) { location.reload() } else { alert('오류가 발생했습니다.') } } ) } </script>

/database/sql.js

getSingleBusinessJoined : async (business_id) => { const [rows] = await promisePool.query(` SELECT * FROM sections S LEFT JOIN businesses B ON S.section_id = B.fk_section_id WHERE business_id = ${business_id} `) return rows[0] }, getMenusOfBusiness : async (business_id) => { const [rows] = await promisePool.query(` SELECT * FROM menus WHERE fk_business_id = ${business_id} `) return rows }, getRatingsOfBusiness : async (business_id) => { const [rows] = await promisePool.query(` SELECT rating_id, stars, comment, DATE_FORMAT( created, '%y년 %m월 %d일 %p %h시 %i분 %s초' ) AS created_fmt FROM ratings WHERE fk_business_id = ${business_id} `) return rows },

/router/index.js

router.get('/business/:id', async function(req, res, next) { const biz = await sql.getSingleBusinessJoined(req.params.id) biz.status_kor = statusKorMap[biz.status] biz.icon = sectionIcons[biz.section_id - 1] const menus = await sql.getMenusOfBusiness(req.params.id) const ratings = await sql.getRatingsOfBusiness(req.params.id) res.render('detail', { biz, menus, ratings }); });

B. 좋아요 수 변경

/database/sql.js

updateMenuLikes : async (id, like) => { return await promisePool.query(` UPDATE menus SET likes = likes + ${like} WHERE menu_id = ${id} `) },

/router/index.js

router.put('/menus/:id', async function(req, res, next) { const result = await sql.updateMenuLikes(req.params.id, req.body.like) res.send(result) });



2. 별점과 코멘트 달기 구현

/database/sql.js

addRating : async (business_id, stars, comment) => { return await promisePool.query(` INSERT INTO ratings (fk_business_id, stars, comment) VALUES (${business_id}, '${stars}', '${comment}') `) }, removeRating : async (rating_id) => { return await promisePool.query(` DELETE FROM ratings WHERE rating_id = ${rating_id} `) }

/router/index.js

router.post('/ratings', async function(req, res, next) { const result = await sql.addRating( req.body.business_id, req.body.stars, req.body.comment ) res.send(result) }); router.delete('/ratings/:id', async function(req, res, next) { const result = await sql.removeRating(req.params.id) res.send(result) });

🤔얄코에게 질문하기질문은 반.드.시 이리로 보내주세요! ( 강의사이트 질문기능 ✖ )

강의에서 이해가 안 되거나 실습상 문제가 있는 부분,
설명이 잘못되었거나 미흡한 부분을 메일로 알려주세요!

답변드린 뒤 필요할 경우 본 페이지에
관련 내용을 추가/수정하도록 하겠습니다.

이메일 주소
yalco@yalco.kr
메일 제목 (반드시 아래 제목을 붙여넣어주세요!)
[질문] 조금 더 깊은 MySQL 5-3

🛑질문 전 필독!!

  • 구글링을 먼저 해 주세요. 들어오는 질문의 절반 이상은 구글에 검색해 보면 1분 이내로 답을 찾을 수 있는 내용들입니다.
  • 오류 메시지가 있을 경우 이를 구글에 복붙해서 검색해보면 대부분 짧은 시간 내 해결방법을 찾을 수 있습니다.
  • 강의 페이지에 추가사항 등 놓친 부분이 없는지 확인해주세요. 자주 들어오는 질문은 페이지에 추가사항으로 업데이트됩니다.
  • "유료파트의 강의페이지는 어디 있나요?" - 각 영상의 시작부분 검은 화면마다 해당 챕터의 강의페이지 링크가 있습니다.
  • 질문을 보내주실 때는 문제가 어떻게 발생했고 어떤 상황인지 등을 구체적으로 적어주세요. 스크린샷을 첨부해주시면 더욱 좋습니다.
🌏 Why not change the world?