How can I remove a 'Belongs To' association in jinzhu/gorm - go

Can anyone help me, how to remove a belongs to association in go-gorm?
Here are my simple models:
type User struct {
gorm.Model
Name string
FirstName string
}
type Customer struct {
Notes []Note `gorm:"polymorphic:Owner;"` // other models can have notes as well
}
type Note struct {
gorm.Model
User User `json:"-"`
UserID uint
OwnerID uint
OwnerType string
}
For "Has many" and "Many to many" associations I can remove the relations. In this example, this works:
db.Model(&customer).Association("Notes").Delete(&note)
However, if I try following:
db.Model(&note).Association("User").Delete(&user)
I get a pointer error:
panic: runtime error: index out of range
... src/github.com/jinzhu/gorm/association.go:242 +0x21ce
The ''user'' and ''note'' objects exist and the relation is there (UserID is set to 1 in the database).

Related

GORM: unsupported Scan, storing driver.Value type int64 into type *models.Team

I have issue with my first GORM usage. I want to load Point with preloaded Team structure. Go throw error that int64 cannot be stored in models.Team. I suppose that I have to use GORM the wrong way, but I am not able to find out why. Database contain data, relation many2many on other structs works fine for me (users in Team struct).
type Point struct {
Id int `gorm:"primaryKey"`
TeamX Team `gorm:"column:team_id;foreignKey:id"` // <<< this struct I want to get
CreatedAt time.Time
Note string
}
func (Point) TableName() string {
return "points"
}
type Team struct {
Id int `gorm:"primaryKey"`
Name string
Users []User `gorm:"many2many:teams_users;"`
}
func (Team) TableName() string {
return "teams"
}
var obj models.Point
log.Println(getDatabase().Preload("Teams").First(&obj, 1).Error.Error())
fmt.Println(obj.Id) // <<< this one loads ok
fmt.Println(obj.TeamX.Id) // <<< this throw error
points table
id int(11), auto_increment
team_id int(11), foreign key teams(id)
createdAt datetime
note text
teams table
id int(11), auto_increment
name text
sql: Scan error on column index 1, name "team_id": unsupported Scan, storing driver.Value type int64 into type *models.Team

How to join multiple tables using GORM without Preload

I currently have 3 tables with relation between them through GORM. I'm looking to query the sellers with all informations about the relation.
Here's my entities:
type ShopType struct {
ID uint `gorm:"primarykey" json:"id"`
Name string `json:"name" xml:"name" form:"name" query:"name"
}
type Shop struct {
ID uint `gorm:"primarykey" json:"id"`
Name string `json:"name" xml:"name" form:"name" query:"name"
ShopType ShopType `gorm:"ShopTypeID;constraint:OnUpdate:CASCADE,OnDelete:RESTRICT;" json:"-"`
}
type Seller struct {
ID uint `gorm:"primarykey" json:"id"`
Firstname string `json:"firstname" xml:"firstname" form:"firstname" query:"firstname"
Lastname string `json:"lastname" xml:"lastname" form:"lastname" query:"lastname"
Shop Shop `gorm:"foreignKey:ShopID;constraint:OnUpdate:CASCADE,OnDelete:RESTRICT;" json:"-"`
}
It's not possible to use Joins instead of Preload like :
db.Model(&models.Seller{}).Joins("Shop").Joins("Shop.ShopType").Find(&results)
?
I have tried this but it doesn't work.
Also I have tried :
db.Model(&models.Seller{}).Joins("JOIN shops s on s.id = sellers.shop_id").Joins("JOIN shop_types st on st.id = s.shop_type_id")
It's work but it didn't fill the props of the Shop and ShopType entities, only the informations about the sellers are filled.
I'm looking to joins my entities using Joins instead of Preload because I want add some clauses to my query like : .Where('Shop.ShopType.Name IN (?)') and that's not possible with the Preload method.
You are almost there with the second query, you can combine the Preload and Where functions with it.
var sellers []Seller
db.Joins("JOIN shops s on s.id = sellers.shop_id").
Joins("JOIN shop_types st on st.id = s.shop_type_id").
Preload("Shop.ShopType").
Where("st.name IN (?)", []string{"Store1", "Store2"}).
Find(&sellers)

Gorm 2, Golang, Auto migrate table with foreign key

import "gorm.io/gorm"
type Object struct {
gorm.Model
ObjectId string `gorm:"primary_key"`
ListItems []ListItem `gorm:"foreignKey:ObjectId;references:ObjectId"`
}
type ListItem struct {
gorm.Model
ObjectId string
Data string
}
I define two objects, then try to auto migrate following the guide
db.Migrator().CreateConstraint(&Object{}, "ListItems")
db.Migrator().CreateConstraint(&Object{}, "fk_object_list_items")
db.AutoMigrate(&Object{}, &ListItem{})
Fails with
ERROR: there is no unique constraint matching given keys for referenced table "blobber_ch
I can't find any examples for this. I tried different permutations of everything.
I suspect the foreign key in the migration does not match the foreign key in the model.
You have two primary_key for Object struct as gorm.Model already have one:
ID uint `gorm:"primarykey"`
You have two otpions : not to use gorm.Model or get rid of ObjectId primary_key and clean references:ObjectId from gorm annotation.
type Object struct {
gorm.Model
ObjectId string
ListItems []ListItem `gorm:"foreignKey:ObjectId;"`
}
type ListItem struct {
gorm.Model
ObjectId string
Data string
}
db.Migrator().CreateConstraint(&Object{}, "ListItems")
db.Migrator().CreateConstraint(&Object{}, "fk_object_list_items")
db.AutoMigrate(&Object{}, &ListItem{})

Gorm extra where 1 <> 1 in many2many

I have two models (structs). User and Group. Those models have many to many relationships.
When I try to create query db.Unscoped().Model(&group).Related(&users, "Users") this returns:
SELECT users.* FROM users INNER JOIN user_groups ON user_groups.owner_id = users.id WHERE (1 <> 1)
The entities are:
type Group struct {
gorm.Model
ID uint `json:"id"`
Name string `json:"name"`
Users []User `gorm:"many2many:user_groups;association_jointable_foreignkey:owner_id"`
}
type User struct {
...
Groups []Group `gorm:"many2many:user_groups;association_jointable_foreignkey:group_id"`
}
Handler
users := []models.User{}
group := models.Group{}
db.Unscoped().Model(&group).Related(&users, "Users")
I don't know the reason to generate extra where.
The problem is fixed.
I have eliminated gorm.Model in struct:
type Group struct {
ID uint `json:"id"`
Name string `json:"name"`
Users []User `gorm:"many2many:user_groups;association_jointable_foreignkey:owner_id"`
}
And In the query:
db.Model(&group).Related(&users)
Regards.

Query with 'has one' association (one-to-one)

I'm playing a bit with Gorm while I'm trying to decide which ORM library fit the most for my needs.
Important to mention that I'm currently working with Sqlite.
Following the guide I created two structs:
type Color struct {
gorm.Model
UserID uint
Name string
}
//User struct define a basic user model
type User struct {
gorm.Model
Username string
Email string
FirstName string
LastName string
Password string
CreationDate time.Time
DOB time.Time
IgnoreMe int `gorm:"-"` // Ignore this field
Color Color `gorm:"foreignkey:ColorRefer"`
ColorRefer uint
}
when I'm creating a DB with
func CreateTables() {
user := dm.User{}
color := dm.Color{}
GormDB.CreateTable(&color)
GormDB.CreateTable(&user)
GormDB.Model(&user).AddForeignKey("ColorRefer", "colors(id)", "CASCADE", "CASCADE")
}
or with:
func CreateTables() {
GormDB.AutoMigrate(&dm.User{},&dm.Color{})
}
Sadly it's not working as I would of expect and create the foreign key automatically, but it's works when I do it manually.
My main problem is when I'm trying to query Users
//QueryByStructExample query users table by the struct non-zero (non-default) fields.
func QueryByStructExample(userStruct dm.User) []dm.User {
var results []dm.User
GormDB.Where(userStruct).Find(&results)
return results
}
I created the following function in a try to query users by email with the color property which is my color struct and I tried to play with a lot with the Model,Related and the Association functions, and nothing seems to work and (I'm avoiding to use join by purpose).
The end result is that it query my User but without the color (only with the ID in my colorRefer)
any suggestion?
Do you mean to preload the Color struct? If yes did you try to query it like that
GormDB.Preload('Color').Where(userStruct).Find(&results)

Resources