JOIN不能像预期的那样使用gorm

mmvthczy  于 2023-09-28  发布在  Go
关注(0)|答案(1)|浏览(165)

我在获取用户的分配角色时遇到一些问题。下面是主要的Get函数:

  1. func (repo *UserRepository) Get(userID int) (*models.User, error) {
  2. user := &models.User{}
  3. err := repo.dbClient.Debug().
  4. Joins("JOIN roles ON users.id = roles.id").Where("users.id = ?", userID).
  5. Select("users.*, roles.roles"). // Assuming you want to find a user by their ID
  6. Find(&user).Error
  7. if err != nil {
  8. log.Printf("failed to fetch user: %v\n", err)
  9. return nil, err
  10. }
  11. return user, nil
  12. }

在这里,我尝试返回用户和他的角色。下面是结构:

  1. type Roles struct {
  2. Id int `json:"id" gorm:"primaryKey"`
  3. Roles string `json:"roles"`
  4. }
  1. type User struct {
  2. Id int `json:"id" gorm:"primaryKey"`
  3. Name string `json:"name"`
  4. Password string `json:"pass"`
  5. ImagePath string `json:"image"`
  6. Roles []Roles ` gorm:"foreignKey:Id"`
  7. }

问题是这两张table都不是空的。但是当我给予一个请求时返回的结果是:

  1. {
  2. "roles": [],
  3. "id": 3,
  4. "name": "fds",
  5. "password": "$2a$14$FqrXrgQJ/gAkHHj/Ac9Ci.nyANGZyU6dotBtKWMk2h9Ac/mnPkeEK",
  6. "image": ""
  7. }

你可以看到角色是空的。
我不知道如何解决这个问题。你能帮帮我吗?

d4so4syb

d4so4syb1#

下面是Preload的例子:

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "os"
  6. "gorm.io/driver/sqlite"
  7. "gorm.io/gorm"
  8. )
  9. type User struct {
  10. Id int `json:"id" gorm:"primaryKey"`
  11. Name string `json:"name"`
  12. Password string `json:"pass"`
  13. ImagePath string `json:"image"`
  14. Roles []Roles `json:"roles" gorm:"foreignKey:user_id;references:id"`
  15. }
  16. func (*User) TableName() string {
  17. return "users"
  18. }
  19. type Roles struct {
  20. Id int `json:"id" gorm:"primaryKey"`
  21. UserId int `json:"user_id"`
  22. Roles string `json:"roles"`
  23. }
  24. func (*Roles) TableName() string {
  25. return "roles"
  26. }
  27. func main() {
  28. db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{
  29. DisableForeignKeyConstraintWhenMigrating: true,
  30. })
  31. if err != nil {
  32. panic(err)
  33. }
  34. defer os.Remove("test.db")
  35. if err := db.AutoMigrate(&User{}, &Roles{}); err != nil {
  36. panic(err)
  37. }
  38. db.Create(&User{Id: 1, Name: "bob", Roles: []Roles{
  39. {Id: 1, Roles: "a,b,c"},
  40. {Id: 2, Roles: "a,b,c"},
  41. }})
  42. var out []*User
  43. db.Model(&User{}).Preload("Roles").Where("id=1").First(&out)
  44. b, _ := json.Marshal(&out)
  45. fmt.Println(string(b))
  46. // output:
  47. // [{"id":1,"name":"bob","pass":"","image":"","roles":[{"id":1,"user_id":1,"roles":"a,b,c"},{"id":2,"user_id":1,"roles":"a,b,c"}]}]
  48. }

在你的代码中,有一些问题:
如果Roles.IdUser.Id,那么User.Roles的类型应该是string而不是[]Roles。因为关系是one to one
因此,在我的示例代码中,我将UserId添加到Roles,以获得关系one to many
更多详情请参见文档:HasManyPreload

展开查看全部

相关问题