在绑定Go Gin之前替换传入的post请求数据?



我做了一个简单的post API,使用Gorm和Go Gin在数据库中存储文章。

API显示问题,当我试图发布类别名称而不是类别id,因为结构体声明它为int32类型

我做了一个简单的函数来获取类别的id而不是名称,但我不知道如何在传入请求中注入它

文章模型

package models
import (
"gorm.io/gorm"
)
type News struct {
Id          int    `gorm:"primary_key;auto_increment;not_null" json:"id"`
Category    int32  `gorm:"category" json:"category" binding:"required"`
CountryID   int32  `gorm:"country_id" json:"country_id" binding:"required"`
LangID      int32  `gorm:"lang_id" json:"lang_id" binding:"required"`
SourceId    int32  `gorm:"source_id" json:"source_id" binding:"required"`
HashtagId   int32  `gorm:"hashtag_id" json:"hashtag_id" binding:"required"`
Title       string `gorm:"title" json:"title" binding:"required"`
Content     string `gorm:"content" json:"content" binding:"required"`
Description string `gorm:"description" json:"description" binding:"required"`
Summery     string `gorm:"summery" json:"summery" binding:"required"`
ImageUrl    string `gorm:"image_url" json:"image_url" binding:"required"`
SourceUrl   string `gorm:"source_url" json:"source_url" binding:"required"`
Author      string `gorm:"author" json:"author" `
}
func CreateArticle(db *gorm.DB, article *News) (err error) {
err = db.Create(article).Error
if err != nil {
return err
}
return nil
}

分类模型

package models
import "gorm.io/gorm"
type Category struct {
Id     int32  `gorm:"primary_key;auto_increment;not_null" json:"id"`
Name   string `gorm:"category_name" json:"category" binding:"required"`
Parent int32  `gorm:"parent" json:"parent"`
}
func GetCategoryByName(db *gorm.DB, category *Category, name string) (err error) {
err = db.Where("LOWER(category_name) Like LOWER(?)", "%"+name+"%").First(category).Error
if err != nil {
return err
}
return nil
}

新闻控制器,实现模型

package controllers
import (
"errors"
"net/http"
"github.com/fouad82/news-app-go/models"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"gorm.io/gorm"
)
type NewsRepo struct {
db *gorm.DB
}
func NewArticle() *NewsRepo {
db := models.InitDb()
return &NewsRepo{db: db}
}
// CreateArticle Create Article
func (repository *NewsRepo) CreateArticle(c *gin.Context) {
var Category models.Category
if err := c.ShouldBindBodyWith(&Category, binding.JSON); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"status": "error", "error": &Category})
return
}
err := models.GetCategoryByName(repository.db, &Category, Category.Name)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
c.AbortWithStatus(http.StatusNotFound)
return
}
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"status": "error", "error": err})
return
}
var CategoryId = Category.Id
var Article models.News
Article.Category = CategoryId
if err := c.ShouldBindBodyWith(&Article, binding.JSON); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"status": "error", "error": err})
return
}
err = models.GetArticleByTitle(repository.db, &Article, Article.Title)
if err == nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
c.AbortWithStatus(http.StatusNotFound)
return
}
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"status": "error", "error": "Title Created Before"})
return
}
createArticle := models.CreateArticle(repository.db, &Article)
if createArticle != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"status": "error", "error": createArticle})
return
}
c.JSON(http.StatusOK, gin.H{"status": "ok", "result": "Article Created"})
}

在这行中,我试图在文章结构中注入int值但它仍然得到错误,我传递字符串值而不是int这是因为它仍然从请求json中读取而不是注入参数

var CategoryId = Category.Id
var Article models.News
Article.Category = CategoryId

我相信你正在使用的函数是超出请求范围,所以基本上不会影响到gin.Context.

我的建议是复制上下文,以便用您更改的数据修改它。篇文章。

...
c.Copy
...

另一件事是关于函数-它正在评估自己-我建议将其排除在CreateArticle函数

createArticle := models.CreateArticle(repository.db, &Article)

我还建议返回已更改的结构,并将其与请求有效负载分开使用-可能您需要为此创建另一个函数:

func (repository *NewsRepo) ChangedArticle(c *gin.Context)News{

changedNews := News{
Id:          0,
Category:    0, // Here is where you change it
CountryID:   0,
LangID:      0,
SourceId:    0,
HashtagId:   0,
Title:       "",
Content:     "",
Description: "",
Summery:     "",
ImageUrl:    "",
SourceUrl:   "",
Author:      "",
}
return changedNews
}

在主函数中使用:

...
createArticle := models.ChangedArticle
...

我可能错过了一些细节,但我希望这个顶级的解释能有所帮助。

最新更新