在gorm v2中,”many to many”关系的错误通常与外键有关。

huangapple go评论89阅读模式
英文:

many to many in gorm v2 error on foreign key

问题

我发现在以下情况下使用Gorm定义多对多关系很困难:

features(feature_id, name, slug)
operations(operation_id, name, slug)
feature_operations(feature_id, operation_id)

type Feature struct {
	FeatureID  int64       `gorm:"primaryKey;column:feature_id" json:"feature_id"`
	Name       string      `validate:"required" json:"name"`
	Slug       string      `json:"slug"`
	Status     string      `json:"status"`
	Operations []Operation `gorm:"many2many:feature_operations;foreignKey:feature_id"`
	appModels.BaseModel
}

当使用feature_id时,我遇到了错误:

列feature_operations.feature_feature_id不存在

当使用id时,我遇到了错误:

无效的外键:id

英文:

I'm finding it difficult to define many to many relationship using Gorm in following cases

features(feature_id, name, slug)
operations(operation_id, name, slug)
feature_operations(feature_id, operation_id)

type Feature struct {
	FeatureID  int64       `gorm:"primaryKey;column:feature_id" json:"feature_id"`
	Name       string      `validate:"required" json:"name"`
	Slug       string      `json:"slug"`
	Status     string      `json:"status"`
	Operations []Operation `gorm:"many2many:feature_operations;foreignKey:feature_id"`
	appModels.BaseModel
}

When using feature_id, I get error

> column feature_operations.feature_feature_id does not exist

When using id, I get error

> invalid foreign key: id

答案1

得分: 3

看起来你没有按照gorm建议的约定命名你的主键列,gorm建议将主键列命名为id

所以在你的情况下,你的foreignKey应该是字段的名称,并且你还需要使用References来指定你想要引用的列。在这里可以看到示例:
https://gorm.io/docs/many_to_many.html#Override-Foreign-Key

你需要的是这样的代码:

type Feature struct {
    FeatureID  int64 `gorm:"primaryKey;column:feature_id"`
	Name       string
	Slug       string
	Operations []Operation `gorm:"many2many:feature_operations;foreignKey:FeatureID;References:OperationID"`
}

type Operation struct {
	OperationID int64 `gorm:"primaryKey;column:operation_id"`
	Name        string
	Slug        string
}

这样,连接表将会是FEATURE_OPERATIONS,有两列FEATURE_FEATURE_IDOPERATION_OPERATION_ID

如果你不喜欢冗余的列名,那么你需要使用两个额外的属性joinForeignKeyjoinReferences来选择你自己的列名,像这样:

gorm:"many2many:feature_operations;foreignKey:FeatureID;joinForeignKey:FeatureID;References:OperationID;joinReferences:OperationID"

所有这些额外的工作都是因为你的主键是FEATURE_IDOPERATION_ID,而不仅仅是ID。如果你可以按照约定重命名列名,你会发现使用gorm会更加容易。

英文:

Looks like you are not using the convention that gorm suggests where you name your primary key columns just id

so in your case your foreignKey should be the name of the field and you also need to use References to specify column that you want to reference. See the example here:
https://gorm.io/docs/many_to_many.html#Override-Foreign-Key

What you need is this:

type Feature struct {
    FeatureID  int64 `gorm:"primaryKey;column:feature_id"`
	Name       string
	Slug       string
	Operations []Operation `gorm:"many2many:feature_operations;foreignKey:FeatureID;References:OperationID"`
}

type Operation struct {
	OperationID int64 `gorm:"primaryKey;column:operation_id"`
	Name        string
	Slug        string
}

After this the join table will be FEATURE_OPERATIONS with two columns FEATURE_FEATURE_ID AND OPERATION_OPERATION_ID

If you dont like the redundant column names then you need to use the two additional attributes joinForeignKey and joinReferences to choose your own names for the columns like so:

gorm:"many2many:feature_operations;foreignKey:FeatureID;joinForeignKey:FeatureID;References:OperationID;joinReferences:OperationID"

All this extra work is needed because your primary keys are FEATURE_ID and OPERATION_ID instead of just ID
If you can rename the column to follow the convention, you will notice life is much easier with gorm

huangapple
  • 本文由 发表于 2023年2月6日 22:52:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/75362899.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定