Golang Gorm Cheatsheet!

26 de junio, 2021 - 3 min

Esta es una collección de snippets que suelo usar dentro de mis proyectos personales. La lista irá crecimiento conforme vaya descubriendo nuevas cosas. Puedes revisar la documentación completa en gorm.io.

¿Cómo instalar GORM?

go get gorm.io/gorm

¿Cómo actualizar GORM?

Similar a la instalación pero con el flag "-u" de update.

go get -u gorm.io/gorm

Crear un simple modelo

package models
import (    "gorm.io/gorm")
type struct Article {  gorm.Model  Title string}

Crear tablas y correr migraciones (Automigrate)

package models
import (    "fmt"
    "gorm.io/driver/postgres"    "gorm.io/gorm")
type User struct {  gorm.Model  Username string  Email string `gorm:"unique" binding:"required"`}
// ddbDsn = postgresql://postgres_user:postgres_pass@database:5432/my-appfunc SetupModels(dbDsn string) *gorm.DB {  db, err := gorm.Open(postgres.Open(dbDsn), &gorm.Config{})  if err != nil {    fmt.Println(err)    panic('Failed to load the database')  }
  db.Automigrate(    &User{},  )
  return db;}

Simple CRUD

package mainimport (    "gorm.io/gorm")
type Article struct {  gorm.Model  Title string}
// createarticle := Article{ Title: "My new article" }db.Create(&article)
// Get Allarticles := []Article{}db.Find(&articles)
// Get oneid := 1db.First(&article, id)
// Updatearticle.Title = "Article title updated!"db.Save(&article)
// Deletedb.Delete(&article)db.Where("id = ?", "2").Delete(&article)

Agregar validaciones a un campo (Validations)

Campo requerido:

package modelsimport (    "gorm.io/gorm")
type Article struct {  gorm.Model  ShortDescription string `binding:"required"`  ShortDescription string `binding:"required"`}

Campo único:

package modelsimport (  "gorm.io/gorm")
type User struct {  gorm.Model  Email string `gorm:"unique" binding:"required"`}

Puedes revisar otros "field tags" aquí.

Crear modelos con relación Many-to-Many con referencia mutua

El nombre de la tabla intermedia será article_categories.

package models
import (    "gorm.io/gorm")
type struct Article {  gorm.Model  Categories   []*Category     `gorm:"many2many:article_categories"`}
type Category struct {  gorm.Model  Articles      []*Article     `gorm:"many2many:article_categories"`}

Obtener data de las relaciones entre tablas (Eager Loading)

Tomando como ejemplo la relación many-to-many, podemos usar el siguiente código para obtener los artículos junto a las categorías de cada uno.

articles := []models.Article{}db.Preload("Categories").Find(&articles)

Crear registro con relación many-to-many sin crear sus registros asociados (Skip Auto Create/Update)

Para many-to-many, GORM hará un upsert (update o insert si el registro no existe) antes de crear la tabla intermedia de referencias. Para omitir este paso podemos usar lo siguiente Omit.

article = models.Article{ Title: "My new article" }category := models.Category{ ID: 1 } // Nuestra db tiene una categoría con el ID 1article.Categories = append(article.Categories, category)
r := db.Omit("Categories.*").Create(&article)

En este ejemplo, nosotros sabemos que nuestra DB tiene un registro Categoría con ID 1. Por lo tanto, no es necesario que GORM intente crear una nueva categoría, simplemente buscamos associar el nuevo artículo con la categoría existente.

Obtener un registro por id (GetById)

Existen diferentes formas. Usando First:

article := models.Article{}
db.First(&article, 10);db.First(&article, "10");db.First(&article, "id = ?", "10");

Usando Where:

article := models.Article{}
db.Where("id = ?", id).First(&article);

Ordenar resultado por un field (OrderBy)

En este caso ordenamos los resultados usando el campo created_at de la tabla Articles.

articles := []models.Article{}db.Order("created_at desc").Find(&articles)db.Order("created_at asc").Find(&articles)

Obtener la cantidad total de registros que tiene una tabla (Count)

count := 0db.Model(&models.Article).Count(&count)

Verificar si el registro fue encontrado (ErrRecordNotFound)

import (  "errors"  "fmt"  "gorm.io/gorm")
name := "design"category := models.Category{}
r := db.Where("name = ?", name).First(&category)
if r.Error != nil {  if !errors.Is(r.Error, gorm.ErrRecordNotFound) {    fmt.Printf("category with name %s doesn't exists", name)  }}

Modificar el contenido antes de guardar en la base de datos (BeforeCreate Hook)

package modelsimport (  "gorm.io/gorm"  "github.com/gosimple/slug")
type Category struct {  gorm.Model  Name string  Slug string  Url string}
func (sc *Category) BeforeCreate(tx *gorm.DB) error {    slg := slug.Make(sc.Name)    url := fmt.Sprintf("/%s/", slg)
    sc.Slug = slg    sc.Url = url
    return nil}

Comparte este artículo: