Golang Gorm参考两列到同一表,插入问题

发布于 2025-01-28 08:23:44 字数 1545 浏览 9 评论 0 原文

最初的想法是从yii

所以,我有这两个模型:

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_realations表中,它的外观是这样的:

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函数值(),类似:

func (item AuthItem) Value() (driver.Value, error) {
    return int64(item.ID), nil 
}

在实现此函数DB.Save之后,但约束/Exournovers/foreferaints/引用停止工作

,所以我的问题:是否有任何选择以正确的方式建立这种关系,或者我如何使用value()函数而不会失去约束?

original idea was to build rbac analog from yii 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:

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:

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

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 ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

┾廆蒐ゝ 2025-02-04 08:23:45

该关系更接近一对多多次有一个父母可以拥有多个孩子,

因为我们指的是与孩子相同的类型如下以下更新模型:

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

插入

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)

authitem 可以通过 自我参考 - has-any 我们不需要第二个表,并且可以将同一表与一个额外的列一起使用,作为参考,

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

我们可以插入记录记录与以前一样

The relation is more near to one-to-many or many-to-many has one parent can have multiple children's

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

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 reference

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

不交电费瞎发啥光 2025-02-04 08:23:45

我得出的结论是,我需要使用许多2频关系,这就是案例的示例:

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

i came to conclusion that i need to use many2many relation and here is example for case:

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"`
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文