英文:
How to delete association (many2many)?
问题
奇怪的行为发生在删除关联时。
查询生成了一个额外的条件,我没有添加。
type Client struct {
gorm.Model
Name string `gorm:"unique;not null" validate:"required,min=1,max=30"`
Kyc_status string `gorm:"not null" validate:"required,min=1,max=30"`
Kyc_remarks string `gorm:"default:null" validate:"omitempty,min=0,max=200"`
Operators []*Operator `gorm:"many2many:client_operators;"`
Op_ids []string `gorm:"-:all" validate:"omitempty,dive,numeric"` // 占位字段,不会成为表的一部分
}
type Operator struct {
gorm.Model
Title string `gorm:"unique;not null" validate:"required,min=1,max=100"`
Email string `gorm:"not null" validate:"required,email"`
Mobile string `gorm:"not null" validate:"required,min=7,max=15,numeric"`
Last_online time.Time `gorm:"default:null" validate:"omitempty"`
Last_ip string `gorm:"default:null" validate:"omitempty,ip"`
Clients []*Client `gorm:"many2many:client_operators;"`
Cli_ids []string `gorm:"-:all" validate:"omitempty,dive,numeric"`
}
// 查找与客户相关的运营商
var client_query *Client
DBconnection.Where("id = ?", pk).Preload("Operators").First(&client_query)
// 删除与客户相关的运营商
DBconnection.Model(&Client{}).Where("client_id = ?", pk).Association("Operators").Delete(&client_query.Operators)
我期望的删除操作是:
[2.000ms] [rows:0] DELETE FROM client_operators
WHERE client_id = 5 AND client_operators
.operator_id
= 1
或者
[2.000ms] [rows:0] DELETE FROM client_operators
WHERE client_operators
.client_id
= 5 AND client_operators
.operator_id
= 1
但实际上它执行的是:
[2.000ms] [rows:0] DELETE FROM client_operators
WHERE client_id = 5 AND client_operators
.client_id
IN (NULL) AND client_operators
.operator_id
= 1
它添加了额外的条件 " AND client_operators
.client_id
IN (NULL) "。
我尝试了 Association().Clear(),但也没有起作用。
英文:
Strange behaviour deleting association happened.
The query generated an extra condition which i did not add.
type Client struct {
gorm.Model
Name string `gorm:"unique;not null" validate:"required,min=1,max=30"`
Kyc_status string `gorm:"not null" validate:"required,min=1,max=30"`
Kyc_remarks string `gorm:"default:null" validate:"omitempty,min=0,max=200"`
Operators []*Operator `gorm:"many2many:client_operators;"`
Op_ids []string `gorm:"-:all" validate:"omitempty,dive,numeric"` // placeholder field, wont be part of table
}
type Operator struct {
gorm.Model
Title string `gorm:"unique;not null" validate:"required,min=1,max=100"`
Email string `gorm:"not null" validate:"required,email"`
Mobile string `gorm:"not null" validate:"required,min=7,max=15,numeric"`
Last_online time.Time `gorm:"default:null" validate:"omitempty"`
Last_ip string `gorm:"default:null" validate:"omitempty,ip"`
Clients []*Client `gorm:"many2many:client_operators;"`
Cli_ids []string `gorm:"-:all" validate:"omitempty,dive,numeric"`
}
// find operators related to client
var client_query *Client
DBconnection.Where("id = ?", pk).Preload("Operators").First(&client_query)
// delete operators related to client
DBconnection.Model(&Client{}).Where("client_id = ?", pk).Association("Operators").Delete(&client_query.Operators)
I expect the deletion to be:
[2.000ms] [rows:0] DELETE FROM `client_operators` WHERE client_id = 5 AND `client_operators`.`operator_id` = 1
OR
[2.000ms] [rows:0] DELETE FROM `client_operators` WHERE `client_operators`.`client_id` = 5 AND `client_operators`.`operator_id` = 1
However it currently does:
[2.000ms] [rows:0] DELETE FROM `client_operators` WHERE client_id = 5 AND `client_operators`.`client_id` IN (NULL) AND `client_operators`.`operator_id` = 1
It adds the extra condition of " AND `client_operators`.`client_id` IN (NULL) "
I tried Association().Clear() and did not do anything too.
答案1
得分: 1
这是因为你将&Client{}
传递给了Model
。
根据gorm文档,你需要首先构建一个具有有效Id
的客户端,像这样:
type Client struct {
gorm.Model
Name string `gorm:"unique;not null" validate:"required,min=1,max=30"`
Kyc_status string `gorm:"not null" validate:"required,min=1,max=30"`
Kyc_remarks string `gorm:"default:null" validate:"omitempty,min=0,max=200"`
Operators []*Operator `gorm:"many2many:client_operators;"`
Op_ids []string `gorm:"-:all" validate:"omitempty,dive,numeric"` // 占位字段,不会成为表的一部分
}
type Operator struct {
gorm.Model
Title string `gorm:"unique;not null" validate:"required,min=1,max=100"`
Email string `gorm:"not null" validate:"required,email"`
Mobile string `gorm:"not null" validate:"required,min=7,max=15,numeric"`
Last_online time.Time `gorm:"default:null" validate:"omitempty"`
Last_ip string `gorm:"default:null" validate:"omitempty,ip"`
Clients []*Client `gorm:"many2many:client_operators;"`
Cli_ids []string `gorm:"-:all" validate:"omitempty,dive,numeric"`
}
// 查找与客户端相关的运营商
var client_query *Client
DBconnection.Where("id = ?", pk).Preload("Operators").First(&client_query)
// 删除与客户端相关的运营商
DBconnection.Model(&Client{ID: pk}).Association("Operators").Delete(&client_query.Operators)
英文:
This is happening because you're passing &Client{}
to Model
.
Looking at gorm docs you need to construct a client with a valid Id
first like this:
type Client struct {
gorm.Model
Name string `gorm:"unique;not null" validate:"required,min=1,max=30"`
Kyc_status string `gorm:"not null" validate:"required,min=1,max=30"`
Kyc_remarks string `gorm:"default:null" validate:"omitempty,min=0,max=200"`
Operators []*Operator `gorm:"many2many:client_operators;"`
Op_ids []string `gorm:"-:all" validate:"omitempty,dive,numeric"` // placeholder field, wont be part of table
}
type Operator struct {
gorm.Model
Title string `gorm:"unique;not null" validate:"required,min=1,max=100"`
Email string `gorm:"not null" validate:"required,email"`
Mobile string `gorm:"not null" validate:"required,min=7,max=15,numeric"`
Last_online time.Time `gorm:"default:null" validate:"omitempty"`
Last_ip string `gorm:"default:null" validate:"omitempty,ip"`
Clients []*Client `gorm:"many2many:client_operators;"`
Cli_ids []string `gorm:"-:all" validate:"omitempty,dive,numeric"`
}
// find operators related to client
var client_query *Client
DBconnection.Where("id = ?", pk).Preload("Operators").First(&client_query)
// delete operators related to client
DBconnection.Model(&Client{ID: pk}).Association("Operators").Delete(&client_query.Operators)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论