Связь позволяет, например, выбрать раздел для статьи и увидеть все статьи этого раздела. При этом в модели описывается отношение, в БД хранится ключ, а интерфейс показывает понятное название записи. Название можно поменять без новой таблицы; изменение способа хранения связи уже затрагивает схему.
Как создать связь
В Content выберите сущность, которая будет владеть связью, и нажмите Create relation:
- Many-to-one — ссылка на одну запись другой сущности.
- One-to-many view — обратный список записей по уже существующей ссылке.
- Many-to-many — набор связанных записей через промежуточную таблицу.
Выберите целевую сущность, обязательность и поле, которое будет служить подписью записи. Сохраните через Finish. Пошаговый пример — статья, раздел и теги.
Где хранится связь
У belongsTo внешний ключ находится в исходной сущности. Например, Article.section использует поле sectionId статьи. Обратная связь hasMany у Section показывает статьи с этим sectionId. Второй внешний ключ для неё не создаётся.
У manyToMany есть один владелец и одна промежуточная таблица. sourceField и targetField ссылаются на первичные ключи сущностей. Изменять состав коллекции нужно со стороны владельца; обратное представление читает ту же связь. Использовать альтернативный уникальный ключ вместо единственного PK в текущем контракте нельзя.
Как БД проверяет связанные записи
Для belongsTo параметр enforce=true включает физическое ограничение внешнего ключа. Доступные действия:
| Событие | Варианты |
|---|---|
| Удаление связанной записи — on-delete | restrict запрещает удаление; setNull очищает ссылку. |
| Изменение ключа — on-update | restrict запрещает изменение; cascade обновляет ссылки. |
setNull требует необязательной ссылки с согласованными настройками. displayField выбирает подпись для пользователя и не участвует в сопоставлении ключей.
Генератор может заблокировать изменение уже выпущенного физического отношения. В этом случае изучите plan и сообщение об ошибке: существующим данным может понадобиться отдельная миграция. Force такую миграцию не заменяет.
Что доступно с обратной стороны
В manyToMany inverseName задаёт обратное имя в модели. inverseDisplayField включает читаемое обратное представление — например, Article.title в карточке Tag. Оно позволяет просмотреть связи, но не менять состав коллекции. Его настройка не создаёт ещё одну промежуточную таблицу.
Система администрирования поддерживает поиск связанных записей с ограничением выдачи, разрешённые фильтры и Related records. Пустая коллекция, недоступная запись и ошибка загрузки показывают разные ситуации. Доступ к обеим сущностям проверяет сервер.
В каком порядке применять изменения
Создайте сущности и совместимые ключи, настройте владельца связи, затем добавьте обратные представления. Просмотрите план, выполните Generate и примените миграции.
Если ограничение имеет состояние NOT VALID, найдите и исправьте нарушающие его строки, затем запустите явную проверку. Удалять данные для обхода проверки не нужно. Подробнее — в миграциях.
Настройки интерфейса собраны в Content: связи, а команды для той же модели — в CLI: отношения.