Ассоциации
Моделируйте связи
«Ассоциации» — бесплатный урок Go Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.
Моделирование связей
Связи GORM сопоставляют отношения между таблицами с полями структур. Выделяют четыре вида: один к одному, один ко многим, принадлежность и многие ко многим.
- Представляйте внешние ключи как поля структур
- Автоматически загружайте связанные данные
- Создавайте связанные записи одновременно
Связь «один ко многим»
У пользователя может быть много публикаций. Родительский объект содержит срез дочерних объектов, а дочерний объект — внешний ключ, ссылающийся на родительский.
type User struct {
gorm.Model
Name string
Posts []Post
}
type Post struct {
gorm.Model
Title string
UserID uint
}Принадлежность к родительскому объекту
С точки зрения дочернего объекта публикация принадлежит пользователю. Добавьте поле User и внешний ключ UserID, чтобы выразить эту связь.
type Post struct {
gorm.Model
Title string
UserID uint
User User
}Связь «один к одному»
Связь «один к одному» похожа на связь «один ко многим», но предполагает одну связанную запись, например один профиль пользователя. Дочерний объект содержит внешний ключ.
type User struct {
gorm.Model
Profile Profile
}
type Profile struct {
gorm.Model
UserID uint
Bio string
}Связь «многие ко многим»
Пользователи и роли связаны отношением «многие ко многим» через промежуточную таблицу. Тег many2many задаёт имя этой таблицы, записываемое как gorm:"many2many:user_roles;" в обратных кавычках после поля Roles.
type User struct {
gorm.Model
// Roles field tag: gorm:"many2many:user_roles;"
Roles []Role
}
type Role struct {
gorm.Model
Name string
}Preload
По умолчанию связанные данные не загружаются. Preload указывает GORM получить связи отдельным запросом, избавляя Вас от ручного отдельного поиска.
var user User
db.Preload("Posts").First(&user, 1)
fmt.Println(len(user.Posts))Вложенный Preload
Вы можете выполнить Preload для нескольких уровней с помощью пути с точками, загрузив публикации пользователя и комментарии каждой публикации одной цепочкой вызовов.
db.Preload("Posts.Comments").First(&user, 1)Рабочая симуляция связей
GORM нужна база данных, поэтому этот запускаемый пример моделирует связь «один ко многим» и предварительную загрузку с помощью срезов в памяти.
package main
import "fmt"
type Post struct {
ID int
UserID int
Title string
}
type User struct {
ID int
Name string
Posts []Post
}
func preload(u *User, all []Post) {
for _, p := range all {
if p.UserID == u.ID {
u.Posts = append(u.Posts, p)
}
}
}
func main() {
u := User{ID: 1, Name: "Ada"}
all := []Post{{1, 1, "Hello"}, {2, 1, "World"}, {3, 2, "Other"}}
preload(&u, all)
fmt.Printf("%s has %d posts\n", u.Name, len(u.Posts))
}Создание вместе со связями
Если передать срез в поле до вызова Create, GORM вставит родительский объект и его дочерние объекты вместе, а внешние ключи будут связаны автоматически.
user := User{Name: "Ada", Posts: []Post{{Title: "Hi"}}}
db.Create(&user)Проблема N+1
Если перебирать родительские объекты и запрашивать дочерние при каждой итерации, получится один запрос на каждый родительский объект — проблема N+1. Preload решает её, объединяя загрузку связанных данных в один дополнительный запрос.
Режим связей
API Association добавляет, заменяет, удаляет или очищает связанные записи без ручной работы с внешними ключами, например db.Model(&user).Association("Posts").Append(&post).
Быстрая проверка
Проверьте свои знания о связях.
Итоги
Вы изучили связи:
- отношения моделей «один к одному», «один ко многим», принадлежность и «многие ко многим»
- внешние ключи являются полями структур, например UserID
- Preload загружает связи и предотвращает проблему N+1
- при создании родительского объекта вместе с дочерними внешние ключи связываются автоматически
- режим связей добавляет, заменяет или очищает отношения
Часто задаваемые вопросы
Урок «Ассоциации» бесплатный?
Да — полный текст урока «Ассоциации» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.
Чему я научусь в уроке «Ассоциации»?
Моделируйте связи Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Go Academy?
Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Ассоциации»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Go Academy?
Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.