Conventions
ID as Primary Key
GORM uses the field with the name ID as the table's primary key by default.
type User struct {
ID string // field named `ID` will be used as a primary field by default
Name string
}You can set other fields as primary key with tag primaryKey
// Set field `UUID` as primary field
type Animal struct {
ID int64
UUID string `gorm:"primaryKey"`
Name string
Age int64
}Also check out Composite Primary Key
Pluralized Table Name
GORM pluralizes struct name to snake_cases as table name, for struct User, its table name is users by convention
TableName
You can change the default table name by implementing the Tabler interface, for example:
type Tabler interface {
TableName() string
}
// TableName overrides the table name used by User to `profiles`
func (User) TableName() string {
return "profiles"
}WARNING
NOTE TableName doesn't allow dynamic name, its result will be cached for future, to use dynamic name, you can use Scopes, for example:
func UserTable(user User) func (tx *gorm.DB) *gorm.DB {
return func (tx *gorm.DB) *gorm.DB {
if user.Admin {
return tx.Table("admin_users")
}
return tx.Table("users")
}
}
db.Scopes(UserTable(user)).Create(&user)Temporarily specify a name
Temporarily specify table name with Table method, for example:
// Create table `deleted_users` with struct User's fields
db.Table("deleted_users").AutoMigrate(&User{})
// Query data from another table
var deletedUsers []User
db.Table("deleted_users").Find(&deletedUsers)
// SELECT * FROM deleted_users;
db.Table("deleted_users").Where("name = ?", "jinzhu").Delete(&User{})
// DELETE FROM deleted_users WHERE name = 'jinzhu';Check out From SubQuery for how to use SubQuery in FROM clause
NamingStrategy
GORM allows users to change the default naming conventions by overriding the default NamingStrategy, which is used to build TableName, ColumnName, JoinTableName, RelationshipFKName, CheckerName, IndexName, Check out GORM Config for details
Column Name
Column db name uses the field's name's snake_case by convention.
type User struct {
ID uint // column name is `id`
Name string // column name is `name`
Birthday time.Time // column name is `birthday`
CreatedAt time.Time // column name is `created_at`
}You can override the column name with tag column or use NamingStrategy
type Animal struct {
AnimalID int64 `gorm:"column:beast_id"` // set name to `beast_id`
Birthday time.Time `gorm:"column:day_of_the_beast"` // set name to `day_of_the_beast`
Age int64 `gorm:"column:age_of_the_beast"` // set name to `age_of_the_beast`
}Timestamp Tracking
CreatedAt
For models having CreatedAt field, the field will be set to the current time when the record is first created if its value is zero
db.Create(&user) // set `CreatedAt` to current time
user2 := User{Name: "jinzhu", CreatedAt: time.Now()}
db.Create(&user2) // user2's `CreatedAt` won't be changed
// To change its value, you could use `Update`
db.Model(&user).Update("CreatedAt", time.Now())You can disable the timestamp tracking by setting autoCreateTime tag to false, for example:
type User struct {
CreatedAt time.Time `gorm:"autoCreateTime:false"`
}UpdatedAt
For models having UpdatedAt field, the field will be set to the current time when the record is updated or created if its value is zero
db.Save(&user) // set `UpdatedAt` to current time
db.Model(&user).Update("name", "jinzhu") // will set `UpdatedAt` to current time
db.Model(&user).UpdateColumn("name", "jinzhu") // `UpdatedAt` won't be changed
user2 := User{Name: "jinzhu", UpdatedAt: time.Now()}
db.Create(&user2) // user2's `UpdatedAt` won't be changed when creating
user3 := User{Name: "jinzhu", UpdatedAt: time.Now()}
db.Save(&user3) // user3's `UpdatedAt` will change to current time when updatingYou can disable the timestamp tracking by setting autoUpdateTime tag to false, for example:
type User struct {
UpdatedAt time.Time `gorm:"autoUpdateTime:false"`
}{% note %} NOTE GORM supports having multiple time tracking fields and track with UNIX (nano/milli) seconds, checkout Models for more details :::
