golang gorm 将两列引用到同一个表,插入问题

最初的想法是从 yii 构建 rbac 模拟https://github.com/yiisoft/yii2/blob/master/framework/rbac/migrations/schema-pgsql.sql


所以,我有这两个模型:


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"`

}

我也已经在 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)

}

我收到此错误:


failed to set value 0x1 to field Parent; failed to set value 0x1 to field Parent 

我尝试使用 gorm 函数 Value(),类似于:


func (item AuthItem) Value() (driver.Value, error) {

    return int64(item.ID), nil 

}

在我实现这个功能后 db.Save 工作,但约束/外键/引用停止工作


所以我的问题是:是否有任何选项可以以正确的方式建立这样的关系,或者我如何在不失去约束的情况下使用 value() 函数?


慕森王
浏览 98回答 2
2回答

胡说叔叔

关系更接近one-to-many或many-to-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"`    AuthRelations []AuthItem `gorm:"many2many:auth_relations; foreignKey:ID; joinForeignKey:Parent; References:ID; joinReferences:Child; constraint:OnUpdate:CASCADE,OnDelete:CASCADE"`}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).Errorif err != nil {  log.Fatalf("cant insert: %v", err)}log.Printf("Relation: %#v\n", &relation)Self-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"`}我们可以像以前一样插入记录

拉丁的传说

我得出结论,我需要使用 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"`}
打开App,查看更多内容
随时随地看视频慕课网APP