英文:
Tell Gorm how to "read"/"write" an interface field in a struct
问题
假设我有以下结构体:
type User struct {
ID uuid.UUID
Name string
Hobbies []Hobby
}
其中Hobby是一个接口,有几个实现,例如:
type ReadingHobby struct {
ID uuid.UUID
userID uuid.UUID
User *User
Books ...
}
type HikingHobby struct {
ID uuid.UUID
userID uuid.UUID
User *User
Routes ...
}
每个爱好都存储在自己的表中,所以按照前面的例子,我们将有一个reading_hobby表和一个hiking_hobby表,它们有自己的表定义和外键。
但是,当我尝试使用gorm从User加载Hobbies时,我得到了不支持的数据类型的错误,这是有道理的,因为gorm不知道如何序列化/反序列化该字段。
我该如何实现呢?我正在尝试创建自定义的序列化器(https://gorm.io/docs/serializer.html),但我无法访问数据库来“查询”所有可能的爱好表,并获取属于用户的所有爱好。
作为最后的解决方案,我考虑使用AfterFind钩子(https://gorm.io/docs/hooks.html#Querying-an-object),但我也希望能够在需要爱好时使用Preload("Hobbies"),而不是总是通过钩子来检索它们。
有什么想法吗?
英文:
Imagine I have the following struct:
type User struct {
ID uuid.UUID
Name string
Hobbies []Hobby
}
where Hobby is an interface with several implementations, as an example:
type ReadingHobby struct {
ID uuid.UUID
userID uuid.UUID
User *User
Books ...
}
type HikingHobby struct {
ID uuid.UUID
userID uuid.UUID
User *User
Routes ...
}
Each hobby is stored in its own table, so following the previous example, we would have a reading_hobby table, and a hiking_hobby table with their own table definition and foreign keys.
But then, when I try to load the Hobbies from an User using gorm, I get Unsopported Data type, which makes sense because gorm does not know how to serialize/deserialize that field.
How can I achieve that? I was checking to create my custom serializer (https://gorm.io/docs/serializer.html), but I don't have access to the db to "query" all the possible hobbies tables and get all the ones that belong to the user.
As a last solution I was thinking to use the AfterFind hook (https://gorm.io/docs/hooks.html#Querying-an-object), but I would also like to be able to use Preload("Hobbies") when I need the hobbies, instead of always retrieving them with the hook.
Any ideas?
答案1
得分: 1
不确定这是否适合您的需求,但我真的没有看到任何更简单的方法。
我认为我会使用两个不同的模型:
一个反映数据库的模型,您可以更轻松地处理gorm:
type User struct {
ID uuid.UUID
Name string
ReadingHobbies []ReadingHobby
HikingHobbies []HikingHobby
...
}
和您原始的带有接口的结构:
type UserInterface struct {
ID uuid.UUID
Name string
Hobbies []Hobby
}
然后有一个转换器转换为接口结构:
func (u User) ToInterface() UserInterface {
return UserInterface{
ID: u.ID,
...
}
}
英文:
Not sure if this would suit your needs, but I don't really see any easier way
I think I would go with two different models :
One reflecting the DB, with which you can more easily handle gorm :
type User struct {
ID uuid.UUID
Name string
ReadingHobbies []ReadingHobby
HikingHobbies []HikingHobby
...
}
And your original struct with the interface :
type UserInterface struct {
ID uuid.UUID
Name string
Hobbies []Hobby
}
Then have a converter to the struct interfacing :
func (u User) ToInterface() UserInterface {
return UserInterface{
ID: u.ID,
...
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论