我做了一个简单的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
...
我可能错过了一些细节,但我希望这个顶级的解释能有所帮助。