Home > Blockchain >  Gorm create and return value many2many
Gorm create and return value many2many

Time:11-14

I want to create a data and then return the value, but the value is related to another table.

User response struct

type UserRespone struct {
    ID        int           `json:"id,omitempty"`
    Email     string        `json:"email"`
    FirstName string        `json:"first_name"`
    LastName  string        `json:"last_name"`
    Address   string        `json:"address"`
    Roles     []roles.Roles `json:"roles" gorm:"many2many:users_roles;foreignKey:ID;joinForeignKey:UserID;references:ID;joinReferences:RolesID"`
}

Roles struct

type Roles struct {
    ID   int `json:"id" gorm:"<-:false;primaryKey"`
    Name string
}

And this is a function to create a data, and I want to return the value [ ]roles.Roles

func (r *UserRepositoryImpl) AuthSignUp(ctx context.Context, req user.AuthSignUp) (user.UserRespone, error) {
    createdUser := req.ToUser()
    
    hashPassword, _ := bcrypt.GenerateFromPassword([]byte(createdUser.Password), bcrypt.DefaultCost)

    createdUser.Password = string(hashPassword[:])

    result := r.Db.
        WithContext(ctx).
        Create(&createdUser)

    for _, rolesID := range req.RolesID {
        userRole := new(user.UsersRoles)

        userRole.UserID = createdUser.ID
        userRole.RolesID = rolesID
        result = r.Db.WithContext(ctx).Create(&userRole)
    }

    return createdUser.ToResponse(), result.Error
}

I want to return the value like this:

user.UserResponse{
        ID:        4,
        Email:     "[email protected]",
        FirstName: "putri",
        LastName:  "cantik",
        Address:   "bonang",
        Roles: []roles.Roles{
            {
                ID: 1,
                Name: "Admin",
            },
            {
                ID: 2,
                Name: "Consumer",
            },
        },
    }

But when I create a data set, I only get values like :

user.UserRespones{
        ID:        4,
        Email:     "[email protected]",
        FirstName: "putri",
        LastName:  "cantik",
        Address:   "bonang",
        Roles:     []roles.Roles(nil),
    }

CodePudding user response:

As far as I can tell, you already have the user data and the role ids. I figure you just want to get the role names as well:

err := r.db.Find(&createdUser.Roles, req.RolesID)
// err handling

That said, your types and names are a bit unclear. UserRespone (note the typo) should probably named like DBUser - it isn't important whether it is used as response or something else, it represents the database entry for an user, right?

Additionally, I can only make assumptions about the type and fields of createdUser and UsersRoles, so I might have missed something.

I figure createdUser is of type UserRespone - but then I would expect that Roles is already complete (and you don't have to query anything at all). If not, then you should introduce a new type for that, e.g. RequestUser (as opposed to DBUser), which only contains Role ids but not Role names. Squeezing the data from the request, the db entry and the response data into the same type is confusing (and a tad too tightly coupled for my taste).

  • Related