Это продолжение серии Express-MVC-1. В этой статье мы будем создавать страницу регистрации для приложения и связанную с ним модель пользователя, представление и соответствующий маршрут регистрации.

ПОЛЬЗОВАТЕЛЬСКАЯ МОДЕЛЬ, ПРОСМОТР И КОНТРОЛЛЕР

ПОЛЬЗОВАТЕЛЬСКАЯ МОДЕЛЬ

  1. Создатьпапку модели. В ней будет храниться модель продолжения и определения для столбцов в таблицах.

Пользователь должен иметь возможность зарегистрироваться на сайте технического блога, используя адрес электронной почты и пароль. Таким образом, таблица пользователей должна иметь столбец электронной почты, столбец пароля и столбец идентификатора пользователя (созданный по умолчанию).

  • Создайте файл index.js. Здесь будут определены отношения между моделями, а также будут экспортированы все модели (любое требование (/ модель) будет ссылаться на индексный файл в нем по умолчанию).

ПРИМЕЧАНИЕ. После того, как все модели будут созданы, мы обновим индексный файл с учетом отношения

//Import model definition from respective model files
const User=require('./User');
//Export the models
module.exports=User;
  • Создайте файл User.js. Здесь будут определены имя таблицы «пользователь», столбцы и их типы данных.
  • Sequelize используйте класс модели, который представляет таблицу в базе данных, и все модели таблиц, используемые в приложении, будут наследоваться от модели.
//Import the Model class from sequelize to define the tables of the application
const { Model, DataTypes } = require('sequelize');
//Import the sequelize instance from connection file
const sequelize=require('../config/connection.js');
//Import bcrypt package to hash the data
const bcrypt = require('bcrypt');
/*
User model extends from the Model class of sequelize package
Sequelize allows to define instance methods on your model class which could be called on the model data
checkPassword is used to compare the password entered by the user and that saved in the table(This will be invoked in the routes)
*/
class User extends Model {
checkPassword(loginPw) {
return bcrypt.compareSync(loginPw, this.password);
}
}
/*
Column data is passed as a nested object.init method is used to define the User model and its attributes
Datatypes class allows to define the data types
Column in user tables are
* id   - id column will be created by default
- Datatypes.Integer will hold only numerical value
- autoincrement:true will increment the values by 1
- primaryKey:true will set the column as primary key of the table
-allowNull:false ensure the column

* email -This will be the column that will hold email data
-Datatype will be string
-unique:true ensure the column will hold unique data
-allowNull:true ensure column contains data

* password -This will be the column that will hold password
-Datatype will be string
-allowNull:true ensure column contains data
-validate: adds inbuilt validation options to the colum data
-Validates len:[8] validate password data is of minimum of length 8
-Syntax : validate:{len:[min,max]} ,if only one argument given that will be the min value

Sequelize allows to pass hooks as second optional argument.hooks can be defined to perform any before or after operation on data.
In this case we define a beforeCreate hook which will use bcrypt package to hash(using hash method) the password before saving it to the password column where newUserdata will be an object with user data containing id, email and password and this function is execute before  create operation on the user table
This newUserdata will be either from seed file or data passed by routes when a new user sign up
* sequelize instance (imported from connection) is also passed along with hooks as second argument
timestamps: false       //This will remove the default timestamp columns(created and updated) from the table
freezeTableName: true,  //By default pluralize the table name,ex 'users' to prevent this freezeTableName should be true
underscored: true,      //This will ensure any columns specified in camel case will be converted to underscore column name format
modelName: "user",      //pass the table name as 'user'
*/
User.init(
{
id: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey:true,
autoIncrement: true,
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true
},
password: {
type: DataTypes.STRING,
allowNull: false,
validate: {
len: [8],
},
},
},
{
hooks: {
beforeCreate: async(newUserData) => {
newUserData.password = await bcrypt.hash(newUserData.password, 10);
return newUserData;
},
},
sequelize,
timestamps: false,
freezeTableName: true,
underscored: true,
modelName: "user",
});
//Export the user model
module.exports = User;

ПРОСМОТР ДЛЯ ПОЛЬЗОВАТЕЛЯ

2) Создать папку представлений. В ней будет храниться код руля для пользовательского интерфейса, связанного с пользовательской моделью, такой как страницы регистрации, входа и выхода.

Создайте папку views внутри этой папки layouts › внутри этой папки создайте файл main.handlebars внутри main.handlebars

Давайте добавим базовый скелет (используя html, bootstrap) для главной страницы технического блога и руля страницы регистрации.

Под рулем будет создана страница с панелью навигации и ссылками на страницы «Главная», «Панель инструментов» и «Выход».

main.handlebars

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tech Blog Site</title>
<!--Google Font Link-->
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,500;1,300&display=swap" rel="stylesheet">
<!-- Bootstrap Link -->
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,400;0,500;1,300&family=Splash&display=swap" rel="stylesheet">
<!--Font Awesome Icon-->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<!--Custom Style sheet from public folder-->
<link rel="stylesheet" href="/css/style.css"/>
</head>
<body>
<nav class="container-fluid d-flex flex-column align-items-start flex-wrap">
<div class="d-flex justify-content-start py-2">
<a href="/home">Home</a>
<a href="/dashboard">Dashboard</a>
<a href="/login" id="login">Login</a>
<a href="/logout" id="logout">Logout</a>
</div>
<h4>The Tech Blog</h4>
</nav>
<main class="d-flex flex-column px-3 py-3">
{{{body}}}
</main>
<!--Bootstrap JS Link-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>
</body>

Под рулем будет создана страница регистрации с формой регистрации с именем пользователя, адресом электронной почты и кнопкой регистрации. И скрипт signup.js связан со страницей, которая будет обрабатывать событие отправки формы.

signup.handlebars

<div class="container my-5 d-flex flex-column py-3 align-items-center" id="login-container">
<h6 class="my-3">SIGNUP</h6>
<form class="container d-flex flex-column align-items-center" id="signup-form">
<div class="form-group my-3 ">
<label for="username" class="my-2">Username</label>
<input type="text" class="form-control px-5" id="signup-username" placeholder="Enter Username">
</div>
<div class="form-group my-4">
<label for="password" class="my-2">Password</label>
<input type="text" class="form-control px-5" id="signup-password" placeholder="Enter Password">
</div>
<div class="form-group my-3">
<button class="btn px-4" id="signup-btn">SignUp</button>
</div>
<p class="error-message text-danger"></p>
</form>
</div>
<script src="/js/signup.js"></script>

ПОЛЬЗОВАТЕЛЬСКИЕ МАРШРУТЫ/КОНТРОЛЛЕР

3) Создать папку контроллера. В ней будут храниться все маршруты, связанные с моделью пользователя. Мы создадим маршрут регистрации, который будет отображать страницу формы регистрации.

Создайте файл index.js в папке контроллера, чтобы определить маршрут регистрации.

Это сообщит приложению, что когда пользователь вводит http://localhost:3002/signup (домен/порт/маршрутный путь) в браузере, он должен отображать signup.handlebars

index.js

//Import the express router package to define the routes for application
const router = require("express").Router();
//Import the User model from index file in models
const User=require('../models');
//SIGN UP ROUTE
router.get("/signup", async (req, res) => {
  res.render("signup");
});
module.exports=router;
  • общая папка — в ней будет храниться код скрипта CSS и JS для пользовательского интерфейса.
  • Создайте папку js внутри общей папки и добавьте новый файл script.js. Позже мы определим обработчик событий для формы регистрации в этом файле.
  • Создайте папку css внутри общей папки и добавьте новый файл styles.css. Добавьте базовый стиль для страниц signup.handlebars и main.handlebars.
*{
margin:0;
padding: 0;
box-sizing: border-box;
}
a,a:hover,a:link,a:visited{
color:var(--nav-color);
text-decoration: none;
}
:root{
--body-color:#e8d5b7;
--text-color:#0e2431;
--link-color:#f9b248;
--secondary-color:#fc3a52;
--nav-color:#0e2431;
}
body{
background-color: #fff;
color: var(--text-color);
}
nav{
height:30%;
background-color: var(--nav-color);
padding:2rem;
}
nav a{
padding: 0 2rem;
color: #fff !important;
}
h4{
background-color: var(--body-color);
border-radius: 0.3rem;
margin-left:2rem;
margin-top:2rem;
padding:0.2rem 0.5rem;
}
/*Styling Sign Up Form*/
#signup-form{
background-color: var(--link-color);
border-radius: 1rem;
width:50%;
}
.btn{
background-color:var(--nav-color);
color: var(--body-color);
}
  • папка seeds. В ней будут храниться тестовые данные и дополнительный код для вставки данных в таблицы. Мы создадим файл user.json со следующими тестовыми данными.

user.json

[{
"username":"sai12345",
"password": "password12345"
},
{
"username": "Lernantino",
"password": "password12345"
},
{
"username": "Amiko",
"password": "password12345"
}]

Вот как теперь должна выглядеть структура папки

Теперь давайте проверим, как маршрут /signup отображает страницу регистрации, запустив сервер с помощью команды node server.js. После запуска сервера введите http:localhost:3002/signup в браузере, чтобы просмотреть страницу регистрации.

Следующая статья будет посвящена проверке входа в систему и отправке формы, а также странице входа.