Declaring Models

Models are normal structs with basic Go types, pointers/alias of them or custom types implementing Scanner and Valuer interfaces

For Example:

1. type User struct {
2. ID           uint
3. Name         string
4. Email        *string
5. Age          uint8
6. Birthday     *time.Time
7. MemberNumber sql.NullString
8. ActivatedAt  sql.NullTime
9. CreatedAt    time.Time
10. UpdatedAt    time.Time
11. }

Conventions

GORM prefer convention over configuration, by default, GORM uses ID as primary key, pluralize struct name to snake_cases as table name, snake_case as column name, and uses CreatedAt, UpdatedAt to track creating/updating time

If you follow the conventions adopted by GORM, you’ll need to write very little configuration/code, If convention doesn’t match your requirements, GORM allows you to configure them

gorm.Model

GORM defined a gorm.Model struct, which includes fields ID, CreatedAt, UpdatedAt, DeletedAt

1. // gorm.Model definition
2. type Model struct {
3. ID        uint           `gorm:"primaryKey"`
4. CreatedAt time.Time
5. UpdatedAt time.Time
6. DeletedAt gorm.DeletedAt `gorm:"index"`
7. }

You can embed it into your struct to include those fields, refer Embedded Struct

Advanced

Field-Level Permission

Exported fields have all permission when doing CRUD with GORM, and GORM allows you to change the field-level permission with tag, so you can make a field to be read-only, write-only, create-only, update-only or ignored

NOTE ignored fields won’t be created when using GORM Migrator to create table

1. type User struct {
2. Name string `gorm:"<-:create"` // allow read and create
3. Name string `gorm:"<-:update"` // allow read and update
4. Name string `gorm:"<-"`        // allow read and write (create and update)
5. Name string `gorm:"<-:false"`  // allow read, disable write permission
6. Name string `gorm:"->"`        // readonly (disable write permission unless it configured)
7. Name string `gorm:"->;<-:create"` // allow read and create
8. Name string `gorm:"->:false;<-:create"` // createonly (disabled read from db)
9. Name string `gorm:"-"`            // ignore this field when write and read with struct
10. Name string `gorm:"-:all"`        // ignore this field when write, read and migrate with struct
11. Name string `gorm:"-:migration"`  // ignore this field when migrate with struct
12. }

Creating/Updating Time/Unix (Milli/Nano) Seconds Tracking

GORM use CreatedAt, UpdatedAt to track creating/updating time by convention, and GORM will set the current time when creating/updating if the fields are defined

To use fields with a different name, you can configure those fields with tag autoCreateTime, autoUpdateTime

If you prefer to save UNIX (milli/nano) seconds instead of time, you can simply change the field’s data type from time.Time to int

1. type User struct {
2. CreatedAt time.Time // Set to current time if it is zero on creating
3. UpdatedAt int       // Set to current unix seconds on updating or if it is zero on creating
4. Updated   int64 `gorm:"autoUpdateTime:nano"` // Use unix nano seconds as updating time
5. Updated   int64 `gorm:"autoUpdateTime:milli"`// Use unix milli seconds as updating time
6. Created   int64 `gorm:"autoCreateTime"`      // Use unix seconds as creating time
7. }

Embedded Struct

For anonymous fields, GORM will include its fields into its parent struct, for example:

1. type User struct {
2. gorm.Model
3. Name string
4. }
5. // equals
6. type User struct {
7. ID        uint           `gorm:"primaryKey"`
8. CreatedAt time.Time
9. UpdatedAt time.Time
10. DeletedAt gorm.DeletedAt `gorm:"index"`
11. Name string
12. }

For a normal struct field, you can embed it with the tag embedded, for example:

1. type Author struct {
2. Name  string
3. Email string
4. }

6. type Blog struct {
7. ID      int
8. Author  Author `gorm:"embedded"`
9. Upvotes int32
10. }
11. // equals
12. type Blog struct {
13. ID    int64
14. Name  string
15. Email string
16. Upvotes  int32
17. }

And you can use tag embeddedPrefix to add prefix to embedded fields’ db name, for example:

1. type Blog struct {
2. ID      int
3. Author  Author `gorm:"embedded;embeddedPrefix:author_"`
4. Upvotes int32
5. }
6. // equals
7. type Blog struct {
8. ID          int64
9. AuthorName  string
10. AuthorEmail string
11. Upvotes     int32
12. }

Fields Tags

Tags are optional to use when declaring models, GORM supports the following tags: Tags are case insensitive, however camelCase is preferred.

Tag Name Description
column column db name
type column data type, prefer to use compatible general type, e.g: bool, int, uint, float, string, time, bytes, which works for all databases, and can be used with other tags together, like not null, size, autoIncrement… specified database data type like varbinary(8) also supported, when using specified database data type, it needs to be a full database data type, for example: MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT
serializer specifies serializer for how to serialize and deserialize data into db, e.g: serializer:json/gob/unixtime
size specifies column data size/length, e.g: size:256
primaryKey specifies column as primary key
unique specifies column as unique
default specifies column default value
precision specifies column precision
scale specifies column scale
not null specifies column as NOT NULL
autoIncrement specifies column auto incrementable
autoIncrementIncrement auto increment step, controls the interval between successive column values
embedded embed the field
embeddedPrefix column name prefix for embedded fields
autoCreateTime track current time when creating, for int fields, it will track unix seconds, use value nano/milli to track unix nano/milli seconds, e.g: autoCreateTime:nano
autoUpdateTime track current time when creating/updating, for int fields, it will track unix seconds, use value nano/milli to track unix nano/milli seconds, e.g: autoUpdateTime:milli
index create index with options, use same name for multiple fields creates composite indexes, refer Indexes for details
uniqueIndex same as index, but create uniqued index
check creates check constraint, eg: check:age > 13, refer Constraints
<- set field’s write permission, <-:create create-only field, <-:update update-only field, <-:false no write permission, <- create and update permission
-> set field’s read permission, ->:false no read permission
- ignore this field, - no read/write permission, -:migration no migrate permission, -:all no read/write/migrate permission
comment add comment for field when migration

Associations Tags

GORM allows configure foreign keys, constraints, many2many table through tags for Associations, check out the Associations section for details