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.
go get gorm.io/gorm
Similar a la instalación pero con el flag "-u" de update.
go get -u gorm.io/gorm
package models import ( "gorm.io/gorm" ) type struct Article { gorm.Model Title string }
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-app func 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; }
package main import ( "gorm.io/gorm" ) type Article struct { gorm.Model Title string } // create article := Article{ Title: "My new article" } db.Create(&article) // Get All articles := []Article{} db.Find(&articles) // Get one id := 1 db.First(&article, id) // Update article.Title = "Article title updated!" db.Save(&article) // Delete db.Delete(&article) db.Where("id = ?", "2").Delete(&article)
Campo requerido:
package models import ( "gorm.io/gorm" ) type Article struct { gorm.Model ShortDescription string `binding:"required"` ShortDescription string `binding:"required"` }
Campo único:
package models import ( "gorm.io/gorm" ) type User struct { gorm.Model Email string `gorm:"unique" binding:"required"` }
Puedes revisar otros "field tags" aquí.
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"` }
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)
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 1 article.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.
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);
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)
count := 0 db.Model(&models.Article).Count(&count)
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) } }
package models import ( "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 }