简体   繁体   中英

Golang Iris: Initialize parent controller's model to child controller's model

I understand that Go is not an object-oriented language but I'm trying to implement a inheritance structure in my Iris controllers as suggested by this article. My main motivation for doing so is to avoid repetition. So far, it has been working for me. Take a look at the following code for example.

// APIController.go (package Controllers)
type APIController struct {
    mvc.C
}
func (c *APIController) Post(data map[string][]string) ([]byte, error) {
    data_parsed := c.ParseFormData(data)
    return json.Marshal(data_parsed)
}

// UserController.go  (package Controllers)
type UserController struct {
    mvc.C
    *APIController
}

func (c *UserController) Post() ([]byte, error) {
    return c.APIController.Post(c.Ctx.FormValues())
}

So far so good.

But I'm finding it difficult to replicate the same strategy for Models. This is what I've done so far

// Model.go (package Models)
type Model struct {
    Id         string `json:"_id"`
    Created_at string `json:"created_at"`
    Updated_at string `json:"updated_at"`
    Deleted_at string `json:"deleted_at"`
}
// implements further set of functions to be used by 'child' models...

// User.go (package Models)
type User struct {
    *Model

    First_name string `json:"first_name"`
    Last_name  string `json:"last_name"`
    Email      string `json:"email"`
    Username   string `json:"username"`
    Password   string `json:"password"`
    Last_login string `json:"last_login"`
}


// APIController.go (package Controllers)
type APIController struct {
    mvc.C
    Model Models.Model
}

// UserController.go  (package Controllers)
type UserController struct {
    mvc.C
    *APIController
}

func (c *UserController) Post() ([]byte, error) {
    c.APIController.Model = new(Models.User) //WRONG!
    return c.APIController.Post(c.Ctx.FormValues())
}

As you can see, the APIController is expecting type Models.Model while UserController is passing *Models.User . The end goal is to have a generic model in APIController that any model from any controller and then is able to call all the functions defined in Models.Model so that I don't have to call those function everywhere.

Is it possible to do so? If not, what might be the best approach to avoid repeating the code?

Update

By using inheritance and single parent model and using that in parent APIController , I want to avoid replicating my filter/CRUD logic. For example, inside UserController , if I want to save a record, then instead of using User.Save(input_data) inside UserController , the Save should ideally be defined inside Models.Model and from APIController , I'm able to call Model.Save(input_data) rather than making the same call from child controllers individually.

First make Model an interface instead of a struct. Have it contain all methods that should be common to all models:

type Model interface {
    // Common methods
}

Then, as long as User implements all those methods, you can have

c.APIController.Model = new(Models.User) // Now works!

One of the common methods could be Save . Otherwise make Save a non-method:

func Save(m Model) error {
    ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM