Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Golang Unresolved type 'models'

I am new to golang and trying to understand why I am getting this error.

Unresolved type 'models'

I have struct declared called Users, as follow:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

package models

import (
    "gorm.io/gorm"
    "time"
)

type Utenti struct {
    gorm.Model
    ID        int       `json:"id"`
    Name      string    `json:"name"`
    Surname   string    `json:"surname"`
    Email     string    `json:"email"`
    Username  string    `json:"username"`
    Password  []byte    `json:"-"`
}

when I try to use this model as a receiver in my auth process:

package authentication

import (
    "github.com/user/repo/internal/models"
    "golang.org/x/crypto/bcrypt"
)

// Encrypt the password before saving to the database
func (user *models.Utenti) HashPassword(password string) {
    hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(password), 14)
    user.Password = hashedPassword
}

func (user *Utenti) ComparePassword(password string) bool {
    err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
    return err == nil
}

the *models.Utenti show the error Unresolved type 'models'

I am using Goland and I tried to invalidate caches, I cleared golang caches. The issue happens only in this specific package (authentication), I can call the models and use it in all other places but this package.

As a work around, I also created the struct in the same package and passed the models.Utenti, as follow:

type Utenti struct {
    models.Utenti
}

and updated the above code to use *Utenti, this seems to have worked but in my actual code;

utenti := Utenti{
        Name:      data["name"].(string),
        Surname:   data["surname"].(string),
        Email:     strings.TrimSpace(data["email"].(string)),
        //....
    }

I am not able to access the Fields of the Struct.

At this point I am really confused and I am sure I missing some knowledge about using receivers from different packages etc.

If anyone can help me to understand this I will be grateful

How to reproduce:

Project Structure

├── cmd
│   └── server
│       └── main.go
├── db
│   └── db.go
├── db-init
├── go.mod
├── go.sum
└── internal
    ├── authentication
    │   ├── auth.go
    ├── models
    │   └── Utenti.go

in internal/models/Utenti.go

package models

import (
    "gorm.io/gorm"
    "time"
)

type Utenti struct {
    gorm.Model
    ID        int       `json:"id"`
    Name      string    `json:"name"`
    Surname   string    `json:"surname"`
    Email     string    `json:"email"`
    Username  string    `json:"username"`
    Password  []byte    `json:"-"`
}

In internal/authentication/auth.go

package authentication

import (
    "github.com/user/repo/internal/models"
    "golang.org/x/crypto/bcrypt"
)

// Encrypt the password before saving to the database
func (user *models.Utenti) HashPassword(password string) {
    hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(password), 14)
    user.Password = hashedPassword
}

func (user *models.Utenti) ComparePassword(password string) bool {
    err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password))
    return err == nil
}

With this you should see that the function HashPassword and ComparePassword, the (user *models.Utenti) is red and shows the mentioned error.

>Solution :

You have:

// Encrypt the password before saving to the database
func (user *models.Utenti) HashPassword(password string) {
    hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(password), 14)
    user.Password = hashedPassword
}

But you can’t define a method on a type defined in another package. That’s why the weird error message: on the receiver func (user *models.Utenti), the thing after the receiver name must be a (not package-qualified) type.

It’s not clear what the "best" solution is, but perhaps you can just define a function:

// HashUtentiPassword updates the users password with a hashed version, to be used before saving to the database.
func HashUtentiPassword(user *models.Utenti, password string) {
    hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(password), 14)
    user.Password = hashedPassword
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading