网站首页 > 技术文章 正文
一篇文章可以有多个标签,一个标签也可以对应多篇文章。这种关系称为“多对多”关系。在数据库设计中,通常通过创建一个中间关联表或联结表(junction table)来实现多对多关系。
这个中间表至少包含两个字段:一个是文章ID,另一个是标签ID。每条记录代表了一篇文章和一个标签之间的关联。这样,一篇文章可以通过这个中间表关联到多个标签,每个标签也可以关联到多篇文章。在 ORM(对象关系映射)中,这种关系也可以通过特定的关系定义来处理,在 GORM 中可以使用 Many2Many 关系。
本节中我只把标签的创建部分完成。它修改自分类的创建,这里就不再对代码进行解释。如果有不懂的,可以查看上一节的内容“Go语言编写个人博客 文章分类”:10.Go语言编写个人博客 文章分类-今日头条 (toutiao.com)
代码如下:
api/tag.go
package api
import (
"errors"
"net/http"
"xblog/models"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
// CreateTag 创建新标签
func CreateTag(c *gin.Context) {
// 从上下文中获取当前用户
currentUser, _ := c.Get("currentUser")
user, ok := currentUser.(*models.JwtClaims)
if !ok {
c.JSON(http.StatusUnauthorized, gin.H{"error": "无法获取用户认证信息"})
return
}
// 获取用户ID
userID := user.UserID
// 查询用户信息并获取用户角色,使用指针调用 GetRole 方法
var userObj models.User
result := models.DB.Where("id = ?", userID).First(&userObj)
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
c.JSON(http.StatusNotFound, gin.H{"error": "用户不存在"})
return
} else if result.Error != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error})
return
}
role, err := userObj.GetRole()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// 检查用户角色,只有为 1 时才有权限
if role != 1 {
c.JSON(http.StatusForbidden, gin.H{"error": "无权创建标签"})
return
}
// 初始化 Tag 结构体
var tag models.Tag
// 绑定请求体到 Tag 结构体
if err := c.ShouldBindJSON(&tag); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()})
return
}
// 保存标签到数据库
if result := models.DB.Create(&tag); result.Error != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": result.Error.Error()})
return
}
// 返回创建的标签
c.JSON(http.StatusOK, gin.H{"tag": tag})
}
models/tag.go
package models
import (
"gorm.io/gorm"
)
type Tag struct {
gorm.Model
Name string `gorm:"type:varchar(63);not null" json:"name"`
Articles []Article `gorm:"many2many:article_tags;"`
}
models/article.go
package models
import (
"gorm.io/gorm"
)
type Article struct {
gorm.Model
Title string `gorm:"type:varchar(255);not null" json:"title" form:"title"`
Content string `gorm:"type:text;not null" json:"content" form:"content"`
UserID uint `gorm:"not null" json:"user_id"`
User User `gorm:"foreignKey:UserID"`
CoverImage string `gorm:"type:varchar(255)" json:"cover_image"`
Images []Image `gorm:"foreignKey:ArticleID"`
CategoryID uint `gorm:"not null" json:"category_id" form:"category_id"`
Category Category `gorm:"foreignKey:CategoryID"`
Tags []Tag `gorm:"many2many:article_tags;"`
}
type Image struct {
gorm.Model
URL string `gorm:"type:varchar(255);not null" json:"url"`
ArticleID uint `gorm:"not null" json:"article_id"`
}
测试命令:curl.sh
登陆并获取token
curl -X POST http://10.0.0.185:8000/api/v1/user/login \
-H "Content-Type: application/json" \
-d '{"username":"user1","password":"passwd123"}'; echo
携带Token创建标签
curl -X POST http://10.0.0.185:8000/api/v1/tag/create \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoyLCJ1c2VybmFtZSI6InVzZXIxIiwiZXhwIjoxNzE1MDU5OTI0LCJpc3MiOiJ4YmxvZyJ9.0uBWCdlIvJFkNzNFeIJ6WKGlGEmWiQDIQ9hJ-ZBrj9Q" \
-d '{"name":"IPv4"}'; echo
大家可以根据以上代码自行测试。
猜你喜欢
- 2024-09-09 混合云资产管理项目(二)(混合云存储产品有哪些)
- 2024-09-09 Go语言进阶之Go语言高性能Web框架Iris项目实战-完善用户管理EP04
- 2024-09-09 数据库与 Go 的交互(go数据库和kegg数据库)
- 2024-09-09 七爪源码:N+1 查询如何烧毁您的数据库
- 2024-09-09 Go的安全编程和防御性编程(防止代码注入)
- 2024-09-09 Vue3+Go 仿抖音项目架构设计与实现
- 2024-09-09 腾讯Go安全指南(腾讯官网最新安全公告)
- 2024-09-09 Grails指南24查询高阶(grails中文参考手册)
- 2024-09-09 Redis优化高并发下的秒杀性能(redis秒杀高并发代码)
- 2024-09-09 10.Go语言编写个人博客 文章分类(基于golang的个人博客系统)
- 02-21走进git时代, 你该怎么玩?_gits
- 02-21GitHub是什么?它可不仅仅是云中的Git版本控制器
- 02-21Git常用操作总结_git基本用法
- 02-21为什么互联网巨头使用Git而放弃SVN?(含核心命令与原理)
- 02-21Git 高级用法,喜欢就拿去用_git基本用法
- 02-21Git常用命令和Git团队使用规范指南
- 02-21总结几个常用的Git命令的使用方法
- 02-21Git工作原理和常用指令_git原理详解
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)