Node.js 뉴스피드 프로젝트 [1일차]
사실 TIL을 일기처럼 쓰고 싶지 않지만 오늘도 역시나 일기다.
새로 알게된 사실이 너무 많고 배운 사실을 적용해보는데 하루 종일이 걸려 노션에는 내가 알아볼 수 있게만 적었기 때문에 티스토리까지 적을 시간은 없을 것 같다.(시간 없더라도 꼭 적자....)
일단 오늘 한 일을 나열해보면 알고리즘 코드카타 - 뉴스피드 프로젝트 발제 - Standard반 수업 - 팀 회의 - 팀 Project 관련 API명세서 작성, ERD 작성, 와이어프레임 작성 - 지난 과제 해설 영상 보며 만들어보기 정도를 했다.
오늘 특히나 인상 깊었던 부분은 과제 해설 영상을 보며 지난 과제에서 commonJS로 만들었던 부분을 ES6문법을 사용해서 만드는데 sequelize 모듈이 commonJS에 최적화되어 있기 때문에 sequelize로 생성된 모든 파일들은 js가 아닌 cjs확장자(commonJS)로 만들어줘야 한다는 부분이 제일 인상깊었다. 그것 뿐만 아니라 index.js에 있는 file부분을 바꿔준 것도 신기했다.
아무튼, 중요한 부분은 어제 하루종일 해도 합쳐지지 않았던 테이블이 강의 영상을 따라 만들었더니 오류하나 없이 합쳐지는 것을 경험했다. 오우...
어제 만든 모델과 오늘 만든 모델의 차이점을 생각해봤을때 차이점은
1. migration의 세부내용(id, password, email, createdAt, updatedAt) 등을 model에 그대로 적용시켰는가.
2. users와 products를 연결해주는 과정(static associate(models))에서 this 바인딩을 해주었는가.
3. foreignkey를 Users 모델에만 주었는가.
이 세 가지 정도가 있었던 것 같다.
그래서 어제 테이블이 제대로 합쳐지지 않은 문제, migration을 재설정해준뒤 db:migrate:undo 이후 테이블이 다시 생성되지 않았던 문제들이 특히 1,2번과 관련이 있지 않았나 싶다.
새벽 1시지만 기분 좋게 해결하고 이제 다시 팀 프로젝트를 만들겸 연습할겸 ES6가 아닌 commonJS로 만들어보려고 한다.
화이팅!
ES6로 변경한 코드
// migrations/user.cjs
'use strict';
/** @type {import('sequelize-cli').Migration} */
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable('Users', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
email: {
allowNull: false,
type: Sequelize.STRING
},
password: {
allowNull: false,
type: Sequelize.STRING
},
name: {
allowNull: false,
type: Sequelize.STRING
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
defaultValue: Sequelize.fn("now")
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
defaultValue: Sequelize.fn("now")
}
});
},
async down(queryInterface, Sequelize) {
await queryInterface.dropTable('Users');
}
};
// migrations/products.cjs
'use strict';
/** @type {import('sequelize-cli').Migration} */
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable('Products', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
userId: {
allowNull: false,
type: Sequelize.INTEGER,
references: {
model: "Users",
key: "id"
}
},
title: {
allowNull: false,
type: Sequelize.STRING
},
description: {
allowNull: false,
type: Sequelize.STRING
},
status: {
allowNull: false,
type: Sequelize.STRING
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
defaultValue: Sequelize.fn("now")
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
defaultValue: Sequelize.fn("now")
}
});
},
async down(queryInterface, Sequelize) {
await queryInterface.dropTable('Products');
}
};
'use strict';
const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const process = require('process');
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.cjs')[env];
const db = {};
let sequelize;
if (config.use_env_variable) {
sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
sequelize = new Sequelize(config.database, config.username, config.password, config);
}
fs
.readdirSync(__dirname)
.filter(file => {
return (
file.indexOf('.') !== 0 &&
file !== basename &&
file.slice(-4) === '.cjs' &&
file.indexOf('.test.js') === -1
);
})
.forEach(file => {
const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes);
db[model.name] = model;
});
Object.keys(db).forEach(modelName => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
// modeles/products.cjs
'use strict';
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Products extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
// define association here
this.belongsTo(models.Users, { as : "user" });
}
}
Products.init(
{
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER,
},
userId: {
allowNull: false,
type: DataTypes.INTEGER,
},
title: {
allowNull: false,
type: DataTypes.STRING,
},
description: {
allowNull: false,
type: DataTypes.STRING,
},
status: {
allowNull: false,
type: DataTypes.STRING,
},
createdAt: {
allowNull: false,
type: DataTypes.DATE,
defaultValue: DataTypes.NOW,
},
updatedAt: {
allowNull: false,
type: DataTypes.DATE,
defaultValue: DataTypes.NOW,
},
},
{
sequelize,
modelName: 'Products',
},
);
return Products;
};
// models/users.cjs
'use strict';
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Users extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
// define association here
this.hasMany(models.Products, { foreignKey: "userId", as: "products" })
}
}
Users.init(
{
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER,
},
email: {
allowNull: false,
type: DataTypes.STRING,
},
password: {
allowNull: false,
type: DataTypes.STRING,
},
name: {
allowNull: false,
type: DataTypes.STRING,
},
createdAt: {
allowNull: false,
type: DataTypes.DATE,
defaultValue: DataTypes.NOW,
},
updatedAt: {
allowNull: false,
type: DataTypes.DATE,
defaultValue: DataTypes.NOW,
},
},
{
sequelize,
modelName: 'Users',
},
);
return Users;
};
'TIL' 카테고리의 다른 글
2023-11-23 TIL (2) | 2023.11.24 |
---|---|
2023-11-22 TIL (0) | 2023.11.23 |
2023_11_20 TIL (2) | 2023.11.20 |
2023_11_16 TIL (1) | 2023.11.17 |
2023_11_15 TIL (1) | 2023.11.16 |