I want to create three tables: Users, Events, Pairs.
In the Pair-table there will be three columns: eventId, user1, user2. So user1, user2 will both reference Users table by id.
I know how to this in sql, but i want to try to use ORM. I've read the docs, but i didn't get how to do that
type User struct {
Id uint64 `gorm:"primarykey"`
TGtag string
IsActive bool
}
type RCEvent struct {
Id uint64 `gorm:"primarykey"`
DateStarted time.Time
IsActive bool
}
type Pair struct {
EventId uint64
UserID1 uint64
UserID2 uint64
}
I've tried to do something with gorm-tags, something like this, but it didn't hepled:
type User struct {
Id uint64 `gorm:"primarykey"`
TGtag string
IsActive bool
}
type RCEvent struct {
Id uint64 `gorm:"primarykey"`
DateStarted time.Time
IsActive bool
Pairs []Pair `gorm:"many2many:pair;"`
}
type Pair struct {
EventId uint64 `gorm:"primarykey"`
UserID1 uint64 `gorm:"primarykey"`
UserID2 uint64 `gorm:"primarykey"`
}
Also, i tried something like and got runtime errors
type User struct {
Id uint64 `gorm:"primarykey"`
TGtag string
IsActive bool
}
type RCEvent struct {
Id uint64 `gorm:"primarykey"`
DateStarted time.Time
IsActive bool
}
type Pair struct {
Event RCEvent
User1 User //`gorm:"foreignkey:UserId"`
User2 User //`gorm:"foreignkey:UserId"`
}
[error] failed to parse value &db.Pair{Event:db.RCEvent{Id:0x0, DateStarted:time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC), IsActive:false}, User1:db.User{Id:0x0, TGtag:"", IsActive:false}, User2:db.User{Id:0x0, TGtag:"", IsActive:false}}, got error invalid field found for struct untitledPetProject/internal/db.Pair's field Event: define a valid foreign key for relations or implement the Valuer/Scanner interface
to use another struct as foreign key you should add it's id as another field in target struct, for your case here is the working example(using gorm example):
package main
import (
"log"
"time"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
type User struct {
gorm.Model
ID uint64 `gorm:"primarykey"`
TGtag string
IsActive bool
}
type RCEvent struct {
gorm.Model
ID uint64 `gorm:"primarykey"`
DateStarted time.Time
IsActive bool
}
type Pair struct {
gorm.Model
ID uint64 `gorm:"primarykey"`
EventID uint64
Event RCEvent
User1ID uint64
User1 User
User2ID uint64
User2 User
}
func main() {
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
// Migrate the schema
err = db.AutoMigrate(&User{})
if err != nil {
log.Fatal(err)
}
err = db.AutoMigrate(&RCEvent{})
if err != nil {
log.Fatal(err)
}
err = db.AutoMigrate(&Pair{})
if err != nil {
log.Fatal(err)
}
// Create
user1 := User{ID: 2, TGtag: "mohammad"}
user2 := User{ID: 3, TGtag: "ali"}
event := RCEvent{ID: 2}
pair := Pair{ID: 2, EventID: 2, Event: event, User1ID: 2, User1: user1, User2ID: 3, User2: user2}
db.Create(&user1)
db.Create(&user2)
db.Create(&event)
db.Create(&pair)
// Read
var user User
db.First(&user, 3) // find product with integer primary key
db.First(&user, "t_gtag = ?", "ali") // find product with code D42
// Update - update product's price to 200
db.Model(&user).Update("is_active", false)
// Update - update multiple fields
db.Model(&user).Updates(User{ID: 4, TGtag: "ahmad"}) // non-zero fields
db.Model(&user).Updates(map[string]interface{}{"Id": 5, "TGtag": "hasan"})
// Delete - delete product
db.Delete(&user, 2)
}