(노드 심화 주차 프로젝트 중)
통으로 짜여 있던 router 메소드들을 controller, service, repository 세 계층으로 분리하는 작업을 하였다. 원하는 만큼 꼼꼼하게 들여다보지 못했어도 여러 번 하다 보니 원리가 눈에 익는 것 같다.
아래는 오늘 진행하며 기록한 작은 팁들이다.
‘/:serviceId’ 와 ‘/:serviceId/pickup’을 다르게 인식할 수 있을까
‘/:serviceId’ 와 ‘/:serviceId/pickup’을 다르게 인식할 수 있을까
⇒ 다르게 인식한다!
// :serviceId로 끝나는 라우터 밑에 :serviceId/mypage 경로를 쓰는 라우터가 쓰여진 상황
// 메소드는 PUT으로 같음. 과연 /:serviceId가 뒤로 붙는 슬래시(/)까지도 잡아먹을까?
router.put('/:serviceId', authMiddleware, async (req, res) => { ... }
router.put('/:serviceId/mypage', authMiddleware, async (req, res => { ... }
보면 알겠지만 슬래시(/)로 플레이스홀더(:)의 탐식을 멈출 수 있다는 것이 확인되었다.
HTML5 커스텀 데이터 속성(custom data attributes)
HTML5 커스텀 데이터 속성(custom data attributes)
이전의 HTML은 태그에 정해진 속성 외에 다른 속성을 지정하는 것은 HTML의 표준을 위반하는 것이었으나, HTML5에서는 특정 요소와 연관되어 있지만 데이터에 대한 확장 가능성을 염두해 두고 data-* 속성을 이용해서 다른 조작을 하지 않고도 의미론적 표준 HTML요소에 추가 정보를 저장할 수 있게 하였다.
예시:
// html에서
<section
id="electriccars"
data-columns="3"
data-index-number="12314"
data-parent="cars">
...
</section>
// jQuery로 접근하기
<script>
$(function() {
$("button").click(function(){
var type=$(this).attr("data-id");
alert(type);
})
});
</script>
참고: https://velog.io/@gga01075/HTML태그에-나만의-커스텀-속성-추가하기-ppec05qv
value 속성을 가지는 html 요소들:
value 속성을 가지는 html 요소들:
<button> | value |
<input> | value |
<meter> | value |
<li> | value |
<option> | value |
<progress> | value |
<param> | value |
따라서 p 태그를 가리키는 제이쿼리 선택자 $('#service-id')
로 .val()
메소드를 호출해도 아무것도 나오지 않는다. 대상 태그가 input
이나 button
, li
같은 경우에만 value 속성을 가질 수 있을 것이므로.
HTML 요소의 텍스트를 불러오기 / 수정하기
$( … ).text()
$( … ).text(’이 값으로 수정’)
HTML 요소의 속성값을 불러오기 / 수정하기
$( … ).attr(’원하는-속성-키’)
$( … ).attr(’원하는-속성-키’, ‘이 값으로 수정’)
HTML 요소의 속성 중 value 값 불러오기
$( … ).val()
에러 Unknown column 'userId' in 'field list'
에러 Unknown column 'userId' in 'field list'
Sequelize로 findAll() 쿼리문을 돌릴 때 자꾸 존재하지 않는 userId라는 컬럼을 SELECT 안에 끼워넣어 부르며 띄우는 에러.
해결 1.
모델 파일에서 userId라는 컬럼을 혹시 추가해 놓았다면 그로 인해 발생할 수 있음. 해당 모델에서 해당 userId 항목 지우고 다시 시도하기.
해결 2.
모델 파일에 userId라는 컬럼도 추가하지 않았고, migration 파일도, 실제 DB의 테이블 모습도 다 정상적이라면 테이블 간의 관계 설정시 문제가 발생한 것일 수 있다.
두 테이블의 일대다 관계를 설정할 땐 양쪽에서 belongsTo와 hasMany를 모두 걸어줘야 하는데 한쪽만 걸어주고 나머지 한 쪽은 안 걸어줬을 시 sequelize가 자동으로 생성하는 ‘테이블명+Id’라는 컬럼이 생겼을 수 있다.
아니면 양쪽 다 서로를 belongsTo와 hasMany로 잘 걸어주었지만 foriegn key를 서로 다른 이름으로 지정하여 발생했을 수 있다.
예를 들면 이렇게 Services : Users = N:1 관계가 있을 때, Service 모델과 User 모델 각각에
// models/service.js
...
class Service extends Model {
static associate(models) {
models.Service.belongsTo(models.User, {
foreignKey: 'customerId',
as: 'customer',
});
}
// models/user.js
...
class User extends Model {
static associate(models) {
models.User.hasMany(models.Service, { foreignKey: 'customerId' }); // foreignKey: 'customer_id' 여기를 이렇게 설정하고 Service.findAll() 호출시 Unknown column 'customer_id' in 'field list' 에러가 뜨게 될 것이다.
}
}
이렇게 서로 belongsTo, hasMany를 각각 걸어주어야 한다. 이 때 foreignKey 값이 서로 어긋나면 어긋난 이름으로 컬럼도 추가되게 되어 상기한 것과 같은 에러가 뜨게 된다.
다시 말해, 만약 User 모델 쪽에 { foreignKey: ‘customer_id’ } 같이 설정해놓았다면 Service.findAll() 등의 조회를 요청할 시 Unknown column 'customer_id' in 'field list' 에러가 뜨게 될 것이다. 저 코드에서 해당 외래키를 ‘컬럼으로 가져야 하는’ 테이블을 Service 쪽이 되는데, Service 테이블에는 정작 ‘customerId’만 있지 ‘customer_id’란 컬럼은 존재하지 않기 때문이다.
아주 도움된 블로그 글:
(검색 키워드”unknown column in 'field list' sequelize 없는 필드명”)
에러 “프론트에서 보내는 PUT body가 백에 전달되지 않음”
에러 “프론트에서 보내는 PUT body가 백에 전달되지 않음”
ajax 폼에 이 데이터를 추가하면 된다:
data:JSON.stringify(jsondata),
contentType:'application/json;charset=UTF-8',
해결된 ajax 콜 예시:
$.ajax({
...
type: 'PUT',
url: `/api/services/${serviceId}/mypage`,
data: JSON.stringify({ status: status }),
contentType: 'application/json; charset=UTF-8',
headers: {
authorization: `Bearer ${localStorage.getItem('token')}`,
},
success: function (response) {
customAlert(response.message);
},
error: function (xhr, status, error) {
console.log(xhr.responseJSON.errorMessage);
},
});
Uploaded by N2T