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)
Related
I have some of this code
type User struct {
Id uint `gorm:"column:id"`
Name string `gorm:"column:name"`
WalletId uint `gorm:"column:wallet_id"`
Wallet Wallet `gorm:"foreignkey:club_id"`
}
type Wallet struct {
Id uint `gorm:"column:id"`
Money uint `gorm:"column:money"`
Valute string `gorm:"column:valute"`
}
I can query users and their wallets like this
var users []users
db.Joins("Wallet").Find(&users)
this will generate stmt like this
SELECT user.id, user.name, user.wallet_id, wallet.id, wallet.Money, wallet.Valute from user join wallet on user.wallet_id = wallet.id
I need to query all users and only `Valute' field from their wallets
I want to use a gorm like
var users []users
db.Joins("Wallet", db.Select("Valute")).Find(&users)
for generate this stmt
SELECT user.id, user.name, user.wallet_id, wallet.Valute from user join wallet on user.wallet_id = wallet.id
For choose a wallet field. But it doesn't work at all. Although there is such a use in the function annotation
// Joins specify Joins conditions
// db.Joins("Account").Find(&user)
// db.Joins("JOIN emails ON emails.user_id = users.id AND emails.email = ?", "jinzhu#example.org").Find(&user)
// db.Joins("Account", DB.Select("id").Where("user_id = users.id AND name = ?", "someName").Model(&Account{}))
func (db *DB) Joins(query string, args ...interface{}) (tx *DB) {
In eager loading by Preload i can choose fields like
db.Limit(1000).Preload("Wallet",
func(db *gorm.DB) *gorm.DB {
return db.Select("valute")
},
).Find(&users)
But this isnt good usage for me, it has a bad perfomance when querying one object. I like to know how can i do the same with Joins
PS: I dont want to use a lightweigh model for wallet which queries only valute, i want to use single model for db presentation
I also want Gorm to support this feature but the best solution I came up with is Smart Select but it requires us to manually write query and select fields
type CustomUser struct {
Id uint `gorm:"column:id"`
Name string `gorm:"column:name"`
Valute string `gorm:"column:valute"`
}
var users []CustomUser
db.Raw("SELECT users.id, users.name, Wallet.valute FROM `users` LEFT JOIN `wallets` `Wallet` ON `users`.`wallet_id` = `Wallet`.`id`").Find(&users)
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{})
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.
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)
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(¬e)
However, if I try following:
db.Model(¬e).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).