持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情
前言:
创建文章基本思路:
00 登录验证token
01 获取用户提交的数据(body中)null?empty?
02 数据验证:登录用户存在数据库中(验证email)
03 生成别名唯一slug
04 存储文章
05 存储标签:文章和标签关系存储/新的标签存储
06 返回文章:slug content description title email
6.1 获取文章、标签、作者
6.2 文章信息进行处理
6.3 响应数据
正文
在路由处使验证token是否存在:
const express = require("express")
const router = express.Router()
const authMiddleware = require("../middleware/authMiddleware")
const {createArticle} = require("../controller/article")
router.post('/',authMiddleware,createArticle)
module.exports=router
验证数据,是否为null?是否符合标准?
const validator = require("validator")
// 创建文章---数据校验
const validateCreateArticle = (title,description,body)=>{
console.log("----------");
let error={}
if(validator.isEmpty(title)){
error.username="title不能为空"
}
if(validator.isEmpty(description)){
error.password="description不能为空"
}
if(validator.isEmpty(body)){
error.email="body不能为空"
}
let validate = Object.keys(error).length<1//true验证通过
return {error,validate}
}
module.exports = validateCreateArticle
然后在控制器中传入从body中获取的方法
let {error,validate} = validateCreateArticle(title,description,body)
if(!validate){
throw new HttpException(401,"数据提交有误","title,description,body不能为空")
}
业务验证:验证作者是否存在?
const {email} = req.user;
const author = await User.findByPk(email); //去数据库中找到这一条数据
if(!author){
throw new HttpException(401,"作者账号不存在","author is not found")
}
以上,完成token验证,完成提交数据的格式校验,完成用户email的验证
可以开始创建文章了,但是在创建之前要先使用一个插件用于生成slug唯一标识,作为每一篇文章的唯一标识。
npm install unique-slug
然后就可以像封装jwt一样写一个方法啦,只需要在需要时调用即可。
var uniqueSlug = require('unique-slug')
let randomSlug = ()=>{
let slug = uniqueSlug()
return slug;
}
module.exports=randomSlug
使用该方法创建slug,并将从body中获取到的数一并存入进article数据库中。
let slug = randomSlug()
let article = await Article.create({
slug,
title,
description,
body,
UserEmail:email //该用户的email也传入方便后续使用
})
以上完成用户创建文章并存储进数据库。
还有一些逻辑要考虑:发布文章时,会增添标签,分新标签与老标签。
目的:要将这些标签一并与文章关联在一起,绑定在一起。
在之前写模块的时候将tag与model进行了多对多的关联:
Artical.belongsToMany(Tag,{
through:"TagList",
uniqueKey:false,
timestamps:false
});
Tag.belongsToMany(Artical,{
through:"TagList",
uniqueKey:false,
timestamps:false
});
他们之间有一个关联表叫TagList,也就是所有多对多的关系会在该表中插入数据,需要我们手动传入。
-
先进行校验,遍历数组,判断tag是否已经在数据库Tag中存在,如果存在那直接就创建标签与文章的关系;如果不存在,则需将该标签存入Tag数据库,再将新标签建立与文章的关系。
-
存储标签与文章关系?
因为是多对多的关联关系,所以打印这条数据__proto__时会发现有许多自动额外增加的方法。 其中包含user的多对多关系,评论的多对多关系,文章的多对多关系都有方法可用
我们在此场景使用addTag的方法向关联表中插入文章与tag关联数据。
if(tags.length>0){
//遍历每一个标签
for (const tag of tags) {
let existTag = await Tag.findByPk(tag)
if(!existTag){ //如果不存在
//存储标签
let newTag = await Tag.create({
name:tag
})
//存储新标签和文章的关系
await article.addTag(newTag) //文章与tag关联数据
}else{ //老标签直接建立关系
await article.addTag(existTag)
}
}
}
最后
响应数据:
根据唯一标识slug获取该文章(包含返回文章对应的标签)
article = await Article.findByPk(slug,{include:Tag})
将该文章返回:
res.status(201)
.json({
status:1,
message:"文章创建成功",
data:article.dataValues //返回文章与对应的标签
})
结果:
每一个slug都与tag形成关联表:
新tag与旧tag不会冲突的重复增加:
后台响应数据: