英文:
gorm : seperate in-database storing model and query sending model
问题
发送gorm模型的有效方法是什么,其中该模型与用于存储数据库中数据的gorm模型不同?
这个Post
模型(结构体)用于存储数据库中的数据。
type Post struct {
gorm.Model
Title string
Body string
}
但是我想使用这个PostRead
gorm模型,将其发送回用户。因为以后可能会添加额外的变量,这些变量不会存储在这个数据库中(或者额外的变量可能来自其他服务或数据库)。
type PostRead struct {
ID string `json:"id" gorm:"primary_key"`
Title string `json:"title"`
Body string `json:"body"`
CreatedAt time.Time `json:"createAt"`
UpdatedAt time.Time `json:"updatedAt"`
...
// 以后要添加的其他变量
}
这是我当前的控制器代码,用于发送数据:
func PostGetAll(c *gin.Context) {
posts, err := services.PostGetAllService()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err})
return
}
c.JSON(http.StatusOK, gin.H{"posts": posts})
}
这是我从数据库获取数据的服务代码:
func PostGetAllService() ([]models.Post, error) {
var posts []models.Post
result := initializers.DB.Find(&posts)
if result.Error != nil {
return nil, errors.New(result.Error.Error())
}
return posts, nil
}
注意:我知道我可以在控制器函数PostGetAll()
中创建一个PostRead
的切片数组,然后使用append()
将posts
(Post
)中的数据添加到切片数组中。
但对我来说,这似乎是一种冗余的解决方法,因此我想知道是否存在更好的解决方案?
更好的高效解决方案
英文:
What is an efficient way of sending a gorm model, which the model is not the same with a gorm model using to store datas in database ?
This Post
model (struct) is used to store datas in DB.
type Post struct {
gorm.Model
Title string
Body string
}
But I want to use this PostRead
gorm model, to be sent to back to user instead. Since there could be extra variables adding to this later, which won't be store in this database. (or the extra variables could be from another services or databases)
type PostRead struct {
ID string `json:"id" gorm:"primary_key"`
Title string `json:"title"`
Body string `json:"body"`
CreatedAt time.Time `json:"createAt"`
UpdatedAt time.Time `json:"updatedAt"`
...
<other variables to be added later>
}
Here's my current controller codes, to send data back :
func PostGetAll(c *gin.Context) {
posts, err := services.PostGetAllService()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err})
return
}
c.JSON(http.StatusOK, gin.H{"posts": posts})
}
And here's my service codes, to get datas from database :
func PostGetAllService() ([]models.Post, error) {
var posts []models.Post
result := initializers.DB.Find(&posts)
if result.Error != nil {
return nil, errors.New(result.Error.Error())
}
return posts, nil
}
NOTE : I knew that I could create a SliceArray of PostRead
in the controller function PostGetAll()
, then use append()
to add datas from posts (Post
) into the SliceArray.
But for me this seems to be abundant way of solving this problem, hence I wonder if there is a better solution existed ?
Better efficient solution
答案1
得分: 1
我不完全确定你的问题,但我会尽力帮助你。
通常我会按照以下方式进行操作,但我相信还有更好的方法。
对于模型,我会将它们准备在一个类似以下的 pkg 中。
// 用于从表单中读取数据。
type CreatePostForm struct {
Title string `json:"title"`
Body string `json:"body"`
}
// 用于与数据库交互。
type Post struct {
gorm.Model
Title string
Body string
}
type Posts []Post
// 用于数据传输对象(发送到 UI 等)。
type PostDto struct {
Title string
Body string
CreatedDate time.Time
CreatedBy string
}
type PostsDto []PostDto
// 将表单数据转换为数据库模型以进行数据库操作。
func (p PostCreateForm) ToCreateModel() (*Post, error) {
// 在这里处理逻辑,基本上是创建一个新的 Post 模型并返回它。
}
// 将数据库模型转换为 DTO 以回复请求等。
func (p Post) ToDto() (*PostDto, error) {
// 在这里处理逻辑,基本上是创建一个新的 PostDto 模型并返回它。
}
// 将多个 Posts 转换为多个 DTOs。
func (ps Posts) ToDto() PostsDto {
dtos := make(PostsDto, len(ps))
for key, post := range ps {
dtos[key] = post.ToDto()
}
return dtos
}
所以基本上在从数据库获取数据后,你可以通过使用 Posts.ToDto()
这样的方法将类型 Posts
转换为类型 PostsDto
。
数据库适配器将位于另一个 pkg 中,它基本上负责读取/写入数据库的工作,但我不会分享它,因为你的问题更多是关于发送另一组数据进行 CRUD 操作。
希望这能帮到你,但我仍然认为可能有更好的方法来做这件事。
英文:
Not entirely sure of your question but let me try to help anyway.
Normally I would do the following but I am sure there are better ways to do it.
For models I will prepare them in a pkg like the following.
// For reading data from form.
type CreatePostForm struct {
Title string `json:"title"`
Body string `json:"body"`
}
// For interactions with database.
type Post struct {
gorm.Model
Title string
Body string
}
type Posts []Post
// For data transfer object (sending over to UI etc).
type PostDto struct {
Title string
Body string
CreatedDate time.Time
CreatedBy string
}
type PostsDto []PostDto
// Convert form data into database model for database operations.
func (p PostCreateForm) ToCreateModel() (*Post, error) {
// Process logic here which is basically creating a new Post model and returning it..
}
// Convert database model into DTO to reply to request etc.
func (p Post) ToDto() (*PostDto, error) {
// Process logic here which is basically creating a new PostDto model and returning it..
}
// Convert many Posts to many DTOs.
func (ps Posts) ToDto() PostsDto {
dtos := make(PostsDto, len(ps))
for key, post := range ps {
dtos[key] = post.ToDto()
}
return dtos
}
So basically from the above after your get the data from the database you can basically converts type Posts to type PostsDto through the use of methods like Posts.ToDto()
.
The DB adaptor will be in another pkg which basically does the work for reading/writing to the database which I will not share since your question is more of sending another set of data for CRUD operations.
Again, I hope this will help you but I still think there might be a better way to do it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论