更改多对多关联表的名称

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

Change name of many-to-many join table

问题

连接表的名称需要为UserLanguages,但是GORM总是将表创建为user_languages

type User struct {
  gorm.Model
  Languages []*Language `gorm:"many2many:UserLanguages;"`
}

type Language struct {
  gorm.Model
  Name string
  Users []*User `gorm:"many2many:UserLanguages;"`
}

我该如何更改连接表的名称?

我在GORM的文档中找到了NamingStrategy
> GORM允许用户通过覆盖默认的NamingStrategy来更改命名约定,需要实现Namer接口。

但是无论我尝试什么,都无法使其工作。也许有人有一个示例?

英文:

The join table's name needs to be UserLanguages. But GORM always creates the table as user_languages.

type User struct {
  gorm.Model
  Languages []*Language `gorm:"many2many:UserLanguages;"`
}

type Language struct {
  gorm.Model
  Name string
  Users []*User `gorm:"many2many:UserLanguages;"`
}

How can I change the name of the join table?

I found NamingStrategy in GORM's docs:
> GORM allows users to change the naming conventions by overriding the default NamingStrategy which need to implements interface Namer

But whatever I tried I couldn't get it work. Maybe someone has an example?

答案1

得分: 1

Gorm将尝试将_CamelCase_转换为_snake_case_,因为这是大多数数据库中表的常见命名约定。

在您的情况下,驼峰命名法转换也将应用于many2many表名注释。例如:如果您使用_AaaBbbCccDdd_,您将得到一个名为_aaa_bbb_ccc_ddd_的连接表。

要更改默认行为,您可以在gorm配置的命名策略中将NoLowerCase值覆盖为true

package main

import (
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
	"gorm.io/gorm/schema"
)

type User struct {
	gorm.Model
	Languages []*Language `gorm:"many2many:UserLanguages;"`
}
type Language struct {
	gorm.Model
	Name  string
	Users []*User `gorm:"many2many:UserLanguages;"`
}

func main() {
	db, err := gorm.Open(sqlite.Open("mydb.db"), &gorm.Config{
		NamingStrategy: schema.NamingStrategy{
			NoLowerCase: true, // << HERE
		},
	})
	if err != nil {
		panic("failed to connect database")
	}
	db.AutoMigrate(&User{})
	db.AutoMigrate(&Language{})
}

如果您真的需要覆盖JoinTableName方法,尽管您可能不需要,您可以像下面示例中所示进行操作,您将得到一个名为_UserLanguages_OVERRIDE_HERE_的连接表。

type MyCustomNaming struct {
	schema.NamingStrategy
}
func (MyCustomNaming) JoinTableName(table string) string {
	return table + "_OVERRIDE_HERE"
}
func main() {
	ns := MyCustomNaming{
		NamingStrategy: schema.NamingStrategy{
			NoLowerCase: true,
		},
	}
	db, err := gorm.Open(sqlite.Open("mydb.db"), &gorm.Config{
		NamingStrategy: ns,
	})
...
英文:

Gorm will try to convert CamelCase to snake_case because that's the common naming convention for tables in most databases.

The camel to snake case conversion will also be applied in your case, on the many2many table name annotation. E.g.: if you'd use AaaBbbCccDdd, you would end up with a join table named aaa_bbb_ccc_ddd

To change the default behavior, you can override the NoLowerCase value to true in the naming strategy of the gorm config.

package main

import (
	&quot;gorm.io/driver/sqlite&quot;
	&quot;gorm.io/gorm&quot;
	&quot;gorm.io/gorm/schema&quot;
)

type User struct {
	gorm.Model
	Languages []*Language `gorm:&quot;many2many:UserLanguages;&quot;`
}
type Language struct {
	gorm.Model
	Name  string
	Users []*User `gorm:&quot;many2many:UserLanguages;&quot;`
}

func main() {
	db, err := gorm.Open(sqlite.Open(&quot;mydb.db&quot;), &amp;gorm.Config{
		NamingStrategy: schema.NamingStrategy{
			NoLowerCase: true, // &lt;&lt; HERE
		},
	})
	if err != nil {
		panic(&quot;failed to connect database&quot;)
	}
	db.AutoMigrate(&amp;User{})
	db.AutoMigrate(&amp;Language{})
}

If you really need to override the JoinTableName method, although you probably don't need to, you can do something as shown below, and you will end up with join table named UserLanguages_OVERRIDE_HERE

type MyCustomNaming struct {
	schema.NamingStrategy
}
func (MyCustomNaming) JoinTableName(table string) string {
	return table + &quot;_OVERRIDE_HERE&quot;
}
func main() {
	ns := MyCustomNaming{
		NamingStrategy: schema.NamingStrategy{
			NoLowerCase: true,
		},
	}
	db, err := gorm.Open(sqlite.Open(&quot;mydb.db&quot;), &amp;gorm.Config{
		NamingStrategy: ns,
	})
...

huangapple
  • 本文由 发表于 2023年4月8日 04:55:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/75961879.html
匿名

发表评论

匿名网友

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

确定