Skip to content

Instantly share code, notes, and snippets.

@mortymacs
Last active November 9, 2022 12:40
Show Gist options
  • Save mortymacs/34945d4efb077b89f5dc8d141ec514d0 to your computer and use it in GitHub Desktop.
Save mortymacs/34945d4efb077b89f5dc8d141ec514d0 to your computer and use it in GitHub Desktop.
GORM model with different attributes
package main
import (
"gorm.io/gorm"
"log"
)
import "gorm.io/driver/postgres"
type StaffAttribute struct {
Department string `gorm:"type:string"`
Role string `gorm:"type:string"`
}
type BotAttribute struct {
DisplayName string `gorm:"type:string"`
Permission string `gorm:"type:string"`
}
type User struct {
ID string `gorm:"type:serial"`
Username string `gorm:"type:string"`
Type string `gorm:"type:string"`
Attributes any `gorm:"serializer:json"`
}
func (u *User) AfterFind(tx *gorm.DB) (err error) {
parsedAttributes := u.Attributes.(map[string]interface{})
if u.Type == "staff" {
u.Attributes = StaffAttribute{
Department: parsedAttributes["Department"].(string),
Role: parsedAttributes["Role"].(string),
}
} else if u.Type == "bot" {
u.Attributes = BotAttribute{
DisplayName: parsedAttributes["DisplayName"].(string),
Permission: parsedAttributes["Permission"].(string),
}
}
return
}
func main() {
dsn := "host=127.0.0.1 user=user password=secret dbname=db"
// Connection.
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatalf("Database connection failed: %s", err)
}
// Migration.
_ = db.AutoMigrate(&User{})
// Data insertion.
db.Create(&User{
Username: "Mort",
Type: "staff",
Attributes: StaffAttribute{
Department: "WS",
Role: "Developer",
},
})
db.Create(&User{
Username: "Cmd",
Type: "bot",
Attributes: BotAttribute{
Permission: "+w",
DisplayName: "Command",
},
})
// Fetch data.
var staffUser User
db.First(&staffUser, 1)
log.Printf("%#v\n", staffUser.Attributes.(StaffAttribute).Department)
var botUser User
db.First(&botUser, 2)
log.Printf("%#v\n", botUser)
log.Printf("%#v\n", botUser.Attributes.(BotAttribute).DisplayName)
}
package main
import (
"gorm.io/gorm"
"log"
)
import "gorm.io/driver/postgres"
type StaffAttribute struct {
Department string `gorm:"type:string"`
Role string `gorm:"type:string"`
}
type BotAttribute struct {
DisplayName string `gorm:"type:string"`
Permission string `gorm:"type:string"`
}
type UserAttribute interface {
StaffAttribute | BotAttribute
}
type User[T UserAttribute] struct {
ID string `gorm:"type:serial"`
Username string `gorm:"type:string"`
Type string `gorm:"type:string"`
Attributes T `gorm:"serializer:json"`
}
func (User[T]) TableName() string {
return "users"
}
func main() {
dsn := "host=127.0.0.1 user=user password=secret dbname=db"
// Connection.
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatalf("Database connection failed: %s", err)
}
// Migration.
_ = db.AutoMigrate(&User[StaffAttribute]{})
// Data insertion.
db.Create(&User[StaffAttribute]{
Username: "Mort",
Type: "staff",
Attributes: StaffAttribute{
Department: "WS",
Role: "Developer",
},
})
db.Create(&User[BotAttribute]{
Username: "Cmd",
Type: "bot",
Attributes: BotAttribute{
Permission: "+w",
DisplayName: "Command",
},
})
// Fetch data.
var staffUser User[StaffAttribute]
db.First(&staffUser, 1)
log.Printf("%#v\n", staffUser)
var botUser User[BotAttribute]
db.First(&botUser, 2)
log.Printf("%#v\n", botUser)
}
package main
import (
"gorm.io/gorm"
"log"
)
import "gorm.io/driver/postgres"
type User struct {
ID string `gorm:"type:serial"`
Username string `gorm:"type:string"`
Type string `gorm:"type:string"`
Attributes map[string]any `gorm:"serializer:json"`
}
type StaffAttribute struct {
Department string `gorm:"type:string"`
Role string `gorm:"type:string"`
}
type Staff struct {
User
Attributes StaffAttribute `gorm:"serializer:json"`
}
func (Staff) TableName() string {
return "users"
}
type BotAttribute struct {
DisplayName string `gorm:"type:string"`
Permission string `gorm:"type:string"`
}
type Bot struct {
User
Attributes BotAttribute `gorm:"serializer:json"`
}
func (Bot) TableName() string {
return "users"
}
func main() {
dsn := "host=127.0.0.1 user=user password=secret dbname=db"
// Connection.
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatalf("Database connection failed: %s", err)
}
// Migration.
_ = db.AutoMigrate(&User{})
// Data insertion.
db.Create(&Staff{
User: User{
Username: "Mort",
Type: "staff",
},
Attributes: StaffAttribute{
Department: "WS",
Role: "Developer",
},
})
db.Create(&Bot{
User: User{
Username: "Cmd",
Type: "bot",
},
Attributes: BotAttribute{
Permission: "+w",
DisplayName: "Command",
},
})
// Fetch data.
var staffUser Staff
db.First(&staffUser, 1)
log.Printf("%#v\n", staffUser)
var botUser Bot
db.First(&botUser, 2)
log.Printf("%#v\n", botUser)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment