使用Gorm更新Post后返回对象的CreatedAt/UpdatedAt为默认时间问题
Gorm更新Post实体后返回对象的CreatedAt/UpdatedAt显示默认时间的问题
我用Gorm更新数据库中的Post实体,数据库里的更新操作已生效,但Gorm返回的对象里CreatedAt和UpdatedAt字段显示为默认时间(0001/01/01...)。
数据库模型
type Base struct { ID uuid.UUID `json:"id" gorm:"primaryKey;default:gen_random_uuid();not null"` CreatedAt time.Time `json:"created_at" gorm:"default:now()"` UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"` DeletedAt *gorm.DeletedAt `gorm:"index" json:"deleted_at" swaggertype:"primitive,string"` } type Post struct { Base Title string `json:"title" gorm:"column:title"` TLDR string `json:"tldr" gorm:"column:tldr"` HTML string `json:"html" gorm:"column:html"` JSON string `json:"json" gorm:"column:json"` BannerImage string `json:"banner_image" gorm:"column:banner_image"` Slug string `json:"slug" gorm:"column:slug"` Status Status `json:"status" gorm:"column:status"` AuthorID uuid.UUID `json:"author_id" gorm:"column:author_id;"` }
更新查询代码
func (p *pgPostRepository) UpdatePost(postDetails *models.Post) (*models.Post, error) { db := p.db.GetClient().(*gorm.DB) err := db.Model(&models.Post{}).Where(&models.Post{ Base: models.Base{ ID: postDetails.ID, }, }).Updates(&postDetails).Error if err != nil { return nil, err } return postDetails, nil }
API响应示例
{ "message": "post updated successfully", "post": { "id": "e4645d79-51da-4e08-85d3-e7409ad6b77b", "created_at": "0001-01-01T00:00:00Z", "updated_at": "0001-01-01T00:00:00Z", "deleted_at": null, "title": "Sample Title", "tldr": "Brief summary of the content", "html": "<p>This is the HTML content.</p>", "json": "{\"key\": \"value\"}", "banner_image": "https://example.com/image.jpg", "slug": "sample-title-1694539437151872840", "status": "draft", "author_id": "96fa719c-358e-4c5d-b878-daee02e2c38b" } }
问题原因及解决方法
原因
你直接返回了传入的postDetails对象,这个对象里的CreatedAt和UpdatedAt字段并没有被Gorm更新——Gorm的Updates方法仅执行数据库更新操作,不会主动将数据库中最新的时间字段值回填到传入的结构体中。
解决方法
有两种常见处理方式:
更新后重新查询
执行完Updates后,用ID查询一次最新的Post数据,返回查询结果:func (p *pgPostRepository) UpdatePost(postDetails *models.Post) (*models.Post, error) { db := p.db.GetClient().(*gorm.DB) // 执行更新 err := db.Model(&models.Post{}).Where("id = ?", postDetails.ID).Updates(postDetails).Error if err != nil { return nil, err } // 重新查询最新数据 var updatedPost models.Post err = db.First(&updatedPost, "id = ?", postDetails.ID).Error if err != nil { return nil, err } return &updatedPost, nil }使用
Save方法(注意字段覆盖问题)
如果postDetails包含所有需要更新的字段,可使用Save方法,它会在更新后自动回填结构体的时间字段:func (p *pgPostRepository) UpdatePost(postDetails *models.Post) (*models.Post, error) { db := p.db.GetClient().(*gorm.DB) err := db.Save(postDetails).Error if err != nil { return nil, err } return postDetails, nil }注意:
Save会更新所有字段(包括未修改的字段),若仅需更新部分字段,建议使用第一种方法或明确指定更新字段。
内容的提问来源于stack exchange,提问作者Sumit Vishwakarma
相关产品推荐
相关产品推荐

