[英]golang gorm reference two columns to same table, problem with insert
original idea was to build rbac analog from yii https://github.com/yiisoft/yii2/blob/master/framework/rbac/migrations/schema-pgsql.sql最初的想法是从 yii 构建 rbac 模拟https://github.com/yiisoft/yii2/blob/master/framework/rbac/migrations/schema-pgsql.sql
so, i have these two models:所以,我有这两个模型:
type AuthItem struct {
ID uint `gorm:"uniqueIndex;primaryKey;auto_increment;column:id" json:"id"`
Name string `gorm:"uniqueIndex;primaryKey;not null;type:varchar(64);column:name" json:"name"`
ItemType int64 `gorm:"type:smallint;not null;column:item_type" json:"item_type"`
Description string `gorm:"size:255;column:description" json:"description"`
}
type AuthRelations struct {
gorm.Model
Parent AuthItem `gorm:"references:id;foreignKey:parent;column:parent" json:"parent"`
Child AuthItem `gorm:"references:id;foreignKey:child;column:child" json:"child"`
}
also i already have some data in auth_items table and i want to make insert into auth_relations table with GORM, and its looks like this:我也已经在 auth_items 表中有一些数据,我想用 GORM 插入到 auth_relations 表中,它看起来像这样:
var relation = models.AuthRelations{
Parent: models.AuthItem{ID: 1},
Child: models.AuthItem{ID: 2},
}
err = db.Save(&relation).Error
if err != nil {
log.Fatalf("cant insert: %v", err)
}
i getting this error:我收到此错误:
failed to set value 0x1 to field Parent; failed to set value 0x1 to field Parent
i tried to use gorm function Value(), something like:我尝试使用 gorm 函数 Value(),例如:
func (item AuthItem) Value() (driver.Value, error) {
return int64(item.ID), nil
}
and after i implement this function db.Save works, but the constraints/foreignKeys/references stop working在我实现这个函数 db.Save 之后,约束/foreignKeys/references 停止工作
so my question : is there any options to make relations like this in right way or how can i use value() function without loosing constraints ?所以我的问题是:有什么选择可以以正确的方式建立这样的关系,或者我如何在不失去约束的情况下使用 value() 函数?
The relation is more near to one-to-many
or many-to-many
has one parent can have multiple children's这种关系更接近one-to-many
或many-to-many
有一个父母可以有多个孩子
Since we are referring to the same type as children we can update the model as below:由于我们指的是与孩子相同的类型,我们可以更新模型如下:
type AuthItem struct {
ID uint `gorm:"primaryKey; column:id" json:"id"`
Name string `gorm:"primaryKey; not null; type:varchar(64); column:name" json:"name"`
ItemType int64 `gorm:"type:smallint; not null; column:item_type" json:"item_type"`
Description string `gorm:"size:255; column:description" json:"description"`
AuthRelations []AuthItem `gorm:"many2many:auth_relations; foreignKey:ID; joinForeignKey:Parent; References:ID; joinReferences:Child; constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
}
AuthItem
can be inserted as AuthItem
可以插入为
var relation = []AuthItem{
{
ID: 1,
Name: "super",
AuthRelations: []AuthItem{
{ ID: 2, Name: "admin" },
{ ID: 3, Name: "owner" },
},
}, {
ID: 2,
Name: "user",
AuthRelations: []AuthItem{
{ ID: 3, Name: "normal" },
{ ID: 5, Name: "client" },
},
},
}
err = db.Save(&relation).Error
if err != nil {
log.Fatalf("cant insert: %v", err)
}
log.Printf("Relation: %#v\n", &relation)
Same can be achieved with Self-Referential-Has-Many
where we don't require second table and can use the same table with one extra column as referenceSelf-Referential-Has-Many
也可以实现同样的效果,我们不需要第二个表,并且可以使用同一个表和一个额外的列作为参考
type AuthItem struct {
ID uint `gorm:"primaryKey; column:id" json:"id"`
Name string `gorm:"primaryKey; not null; type:varchar(64); column:name" json:"name"`
ItemType int64 `gorm:"type:smallint; not null; column:item_type" json:"item_type"`
Description string `gorm:"size:255; column:description" json:"description"`
Parent *uint `gorm:"column: parent;" json:"parent"`
AuthRelations []AuthItem `gorm:"foreignKey:Parent"; constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`
}
we can insert record the same manner as we did before我们可以像以前一样插入记录
i came to conclusion that i need to use many2many relation and here is example for case:我得出的结论是我需要使用 many2many 关系,这里是案例示例:
type AuthItem struct {
ID uint `gorm:"uniqueIndex;primaryKey;auto_increment" json:"id"`
Name string `gorm:"unique;not null;type:varchar(64);column:name" json:"name"`
ItemType int64 `gorm:"type:smallint;not null;column:item_type" json:"item_type"`
Description string `gorm:"size:255;column:description" json:"description"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
DeletedAt time.Time `gorm:"default:null" json:"deleted_at"`
}
type AuthRelations struct {
ID uint `gorm:"uniqueIndex;primaryKey;auto_increment" json:"id"`
Parent []AuthItem `gorm:"many2many:prnt_authitem_parent;References:Name;constraint:OnUpdate:CASCADE,OnDelete:SET NULL;" json:"parent"`
Child []AuthItem `gorm:"many2many:chld_authitem_child;References:Name;constraint:OnUpdate:CASCADE,OnDelete:SET NULL;" json:"child"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
DeletedAt time.Time `gorm:"default:null" json:"deleted_at"`
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.