Reputation: 322
I am new to golang and trying to make API server using gin + gorm.
I tried to build the code below but I am getting type *gorm.DB has no field or method GetUsers
error.
This is a very simple API server and only I want to do is get all users from users
table.
package models
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/postgres"
)
var db *gorm.DB
func init() {
var err error
db, err = gorm.Open("postgres", "host=localhost dbname=test user=postgres password=test sslmode=disable")
if err != nil {
return err
}
}
type User struct {
ID int `json:"id"`
Username string `json:"name"`
}
func NewUser(id int, name string) User {
return User{
ID: id,
Username: name,
}
}
// UserRepository
type UserRepository struct {
}
func NewUserRepository() UserRepository {
return UserRepository{}
}
func (m UserRepository) GetUsers() []*User {
var users []*User
has, _ := db.GetUsers(&users)
if has {
return users
}
return nil
}
I implemented GetUsers()
in controllers/user.go
and I also created users
table.
I have no idea why it says no field or method GetUsers
.Someone give me an advice to solve this.
package controllers
import (
"api-server/models"
)
type User struct {
}
func NewUser() User {
return User{}
}
func (c User) GetUsers() interface{} {
repo := models.NewUserRepository()
user := repo.GetUsers()
return user
}
Upvotes: 0
Views: 9670
Reputation: 51
Tried to comment back to your question under Sergey's answer above, but I don't have the privilege since I'm new here.
As Sergey said, I cannot see GetUsers function in gorm.DB
struct. If you do db.Raw("select * from users").Scan(&users)
, you cannot (don't need to either) assign two variables to the statement. Instead, just:
db.Raw("select * from users").Scan(&users)
This is because DB.Scan() returns only one result variable in your DB implementation:
// Scan scan value to a struct
func (s *DB) Scan(dest interface{}) *DB {
return s.clone().NewScope(s.Value).Set("gorm:query_destination",dest).callCallbacks(s.parent.callbacks.queries).db
}
That is because you didn't actually implement GetUsers
for gorm.DB
. What you did was - define a struct in controllers
package named User
, and attach a GetUsers
method to that struct. Inside controllers/User.GetUsers
you called repo.GetUsers
which internally tries to call db.GetUsers
. db
is of type *gorm.DB
which does not have GetUsers
method defined.
One way to fix is as Sergey suggested, just do db.Raw(...).Scan(...)
.
If you really want to encapsulate gorm.DB and makes GetUsers
look more native from the db connection, one thing you can try is:
type MyDB struct {
gorm.DB
}
func (m *MyDB) GetUsers() []*Users {
// do things like m.Raw(...).Scan(...)
}
And in your models, you declare db
as type *MyDB
instead of *gorm.DB
.
For more official docs about this embedding technique, checkout https://golang.org/doc/effective_go.html#embedding
Upvotes: 1
Reputation:
If I see in your code I don't see GetUsers function
db this *gorm.DB and not have GetUsers
You need like this
db..Raw("select * from users").Scan(&users)
Upvotes: 1