gogo-gormrevel

How to query a GORM Model


I'm attempting to query a database given a model, and I'm getting a blank model as a response. I'm using Revel framework and GORM to create the model and query the database.

app.go

package controllers

import (
    "github.com/revel/revel"
    "route/to/models"
)

type App struct {
    *revel.Controller
    GormController
}

func (c App) Index() revel.Result {
    accounts := models.Account{}
    account := c.DB.Find(accounts)

    return c.RenderJSON(account)
}

gorm.go

package controllers

import (
    _ "github.com/jinzhu/gorm/dialects/postgres"
    "github.com/jinzhu/gorm"
    r "github.com/revel/revel"
)
type GormController struct {
    *r.Controller
    DB *gorm.DB
}

// it can be used for jobs
var Gdb *gorm.DB

// init db
func InitDB() {
    var err error
    // open db
    Gdb, err = gorm.Open("postgres", "host=hostname port=5432 user=postgres password=password dbname=some_db_name sslmode=disable")
    Gdb.LogMode(true) // Print SQL statements
    if err != nil {
        r.ERROR.Println("FATAL", err)
        panic(err)
    }
}

func (c *GormController) SetDB() r.Result {
    c.DB = Gdb
    return nil
}

Not sure where I'm going wrong, ultimately I want to do a select * from accounts;

Note: I can run a migration and create in the Index() function and the data is handled correctly.


Solution

  • When populating a struct from the database, you need to pass a pointer for GORM to be able to populate it. Otherwise it's pass-by-value and GORM populates a copy and you never see it.

    And if you want to get all accounts you should pass a pointer to a slice of accounts. Regarding pointers versus values, a slice is different from a struct in that the underlying array can still be modified even in pass-by-value, but outside the function the slice length (and capacity) won't change even as the array is populated within the function, so it still won't behave as expected without a pointer.

    And you should check Error afterward:

    accounts := make([]models.Account, 0)
    if err := c.DB.Find(&accounts).Error; err != nil {
         if gorm.IsRecordNotFoundError(err) {
              // handle not found
         } else {
              // print/log/return error
         }
         return
    }
    
    // do something with accounts