2

I have next GORM model

package entity

import (
    "github.com/jinzhu/gorm"
)

type InterfaceEntity interface {
}

type User struct {
    InterfaceEntity
    gorm.Model
    Name string
}

I try to pass GORM entity type into base crud repository. My base crud repository:

package repository

import (
    "billingo/model/entity"
    "fmt"
    "github.com/jinzhu/gorm"
    "reflect"
)

type CrudRepository struct {
    *BaseRepository
}

func NewCrudRepository(db *gorm.DB) CrudRepositoryInterface {
    repo := NewBaseRepository(db).(*BaseRepository)
    return &CrudRepository{repo}
}

func (c CrudRepository) Find(id uint, item entity.InterfaceEntity) entity.InterfaceEntity {
    fmt.Println("--- Initial")
    var local entity.User
    fmt.Println("--- local: ", reflect.TypeOf(local), local)
    fmt.Println("--- Item:  ", reflect.TypeOf(item), item)


    fmt.Println("--- Values")
    c.db.First(&local, id)
    fmt.Println("--- local: ", reflect.TypeOf(local), local)
    c.db.First(&item, id)
    fmt.Println("--- Item: ", reflect.TypeOf(item), item)
    return item
}

As you can see here are item and local variables in Find() method.

I pass item using next way from service:

func (c CrudService) GetItem(id uint) entity.InterfaceEntity {
    var item entity.User
    return c.repository.Find(id, item)
}

It seems what local and item must be equals and behavior must be equivalent.

But output is

--- Initial
--- local:  entity.User {<nil> {0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} }
--- Item:   entity.User {<nil> {0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} }
--- Values
--- local:  entity.User {<nil> {1 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} test 1}
--- Item:  entity.User {<nil> {0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} }
INFO[0000] User info                                     user="{<nil> {0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} }" user-id=1

(/home/mnv/go/src/billingo/model/repository/CrudRepository.go:29) 
[2019-05-17 17:07:37]  unsupported destination, should be slice or struct 

item passed from service leads to message

unsupported destination, should be slice or struct

How to pass item correctly, I need behavior like with local?

2 Answers 2

2

Gorm doesn't want to unmarshal the data into your empty interface type.

Even though you are passing in a struct that implements that particular interface, it still remains typed as the interface after passed. You need to cast that item interface back to your User struct.

Like item.(entity.User)

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for response. item.(entity.User) works well. But I need to create more abstract method what don't knows about type of model. I'm novice in Golang. May I use something like item(reflect.TypeOf(item))?
0

Oh, I has fixed it.

Now repository method Find called from service with &item:

func (c CrudService) GetItem(id uint) entity.InterfaceEntity {
    var item entity.User
    return c.repository.Find(id, &item)
}

And repository method pass item without &:

func (c CrudRepository) Find(id uint, item entity.InterfaceEntity) entity.InterfaceEntity {
    c.db.First(item, id)
    return item
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.