Нет необходимости создавать PermissionToRole
, вы можете просто использовать многие ко многим, которые сериализуются в JSON формат, который вы хотите. Если вы уверены, что вам нужно определить отдельную таблицу, вам нужно убедиться, что имена столбцов совпадают (как имена столбцов таблицы, так и ссылки), вот пример:
type Role struct {
RoleID string `gorm:"type:varchar(25); primary_key" json:"id"`
Name string `gorm:"type:varchar(50)" json:"name"`
Description string `gorm:"type:text(250)" json:"description"`
CreatedAt string `gorm:"type:timestamp" json:"createdAt"`
Permissions []Permission `gorm:"many2many:permission_to_roles;association_foreignkey:perm_id;foreignkey:role_id;association_jointable_foreignkey:perm_id;jointable_foreignkey:role_id;" json:"permissions"`
}
type Permission struct {
PermID string `json:"id" gorm:"type:varchar(25); primary_key"`
Name string `json:"name" gorm:"type:varchar(50)"`
Description string `json:"description" gorm:"text(250)"`
}
type PermissionToRole struct {
RoleID string `json:"-" gorm:"type:varchar(25); primary_key"`
PermID string `json:"-" gorm:"type:varchar(25); primary_key"`
}
и полный код который использует это:
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/sqlite"
"log"
"os"
)
type Role struct {
RoleID string `gorm:"type:varchar(25); primary_key" json:"id"`
Name string `gorm:"type:varchar(50)" json:"name"`
Description string `gorm:"type:text(250)" json:"description"`
CreatedAt string `gorm:"type:timestamp" json:"createdAt"`
Permissions []Permission `gorm:"many2many:permission_to_roles;association_foreignkey:perm_id;foreignkey:role_id;association_jointable_foreignkey:perm_id;jointable_foreignkey:role_id;" json:"permissions"`
}
type Permission struct {
PermID string `json:"id" gorm:"type:varchar(25); primary_key"`
Name string `json:"name" gorm:"type:varchar(50)"`
Description string `json:"description" gorm:"text(250)"`
}
type PermissionToRole struct {
RoleID string `json:"-" gorm:"type:varchar(25); primary_key"`
PermID string `json:"-" gorm:"type:varchar(25); primary_key"`
}
func sample() error {
_ = os.Remove("test.db") // Remove file to make sure DB is empty
db, err := gorm.Open("sqlite3", "test.db")
if err != nil {
return fmt.Errorf("open DB failed: %w", err)
}
defer db.Close()
db.LogMode(true)
err = db.AutoMigrate(
&Role{},
&Permission{},
).Error
if err != nil {
return fmt.Errorf("migration failed: %w", err)
}
// Put some sample data in DB
sampleRoles := []Role{
{RoleID: "role0", Name: "n0"},
{RoleID: "role1", Name: "n1"},
{RoleID: "role2", Name: "n2"},
{RoleID: "role3", Name: "n3"},
}
for idx := range sampleRoles {
err = db.Create(&sampleRoles[idx]).Error
if err != nil {
return fmt.Errorf("failed to create: %w", err)
}
}
samplePermissions := []Permission{
{PermID: "perm0"},
{PermID: "perm1"},
{PermID: "perm2"},
{PermID: "perm3"},
}
for idx := range samplePermissions {
err = db.Create(&samplePermissions[idx]).Error
if err != nil {
return fmt.Errorf("failed to create: %w", err)
}
}
sampleM2m := []PermissionToRole{
{RoleID: "role2", PermID: "perm3"},
{RoleID: "role2", PermID: "perm1"},
{RoleID: "role2", PermID: "perm0"},
}
for idx := range sampleM2m {
err = db.Create(&sampleM2m[idx]).Error
if err != nil {
return fmt.Errorf("failed to create: %w", err)
}
}
// Do query
var role Role
err = db.Preload("Permissions").First(&role, "role_id = ?", "role2").Error
if err != nil {
return fmt.Errorf("error in query: %w", err)
}
fmt.Printf("%+v\n", role)
return nil
}
func main() {
err := sample()
if err != nil {
log.Fatal(err)
}
}