Собственная ORM-модель на D7 описывается классом-наследником
Bitrix\Main\Entity\DataManager с явным перечислением
полей таблицы и их типов. Разберём базовые типы полей, связи между
сущностями и валидацию — то, ради чего вообще стоит писать
ORM-модель, а не работать с таблицей через прямой SQL.
Минимальная модель
<?php
namespace Vendor\Module;
use Bitrix\Main\Entity\DataManager;
use Bitrix\Main\Entity\IntegerField;
use Bitrix\Main\Entity\StringField;
use Bitrix\Main\Entity\DatetimeField;
class TaskTable extends DataManager
{
public static function getTableName(): string
{
return 'vendor_module_task';
}
public static function getMap(): array
{
return [
new IntegerField('ID', ['primary' => true, 'autocomplete' => true]),
new StringField('TITLE', ['required' => true]),
new IntegerField('STATUS', ['default_value' => 0]),
new DatetimeField('CREATED_AT', ['default_value' => new \Bitrix\Main\Type\DateTime()]),
];
}
}
Имя таблицы и карта полей — единственное, что обязательно переопределить. Остальные возможности (связи, валидаторы, вычисляемые поля) добавляются по необходимости поверх этого минимума.
Основные типы полей
IntegerField— целое число.StringField— строка (VARCHAR).TextField— длинный текст (TEXT).BooleanField— булево значение, хранится как 'Y'/'N' по умолчанию.DatetimeField/DateField— дата и время, требуют объектBitrix\Main\Type\DateTime.FloatField— число с плавающей точкой.EnumField— значение из фиксированного списка.ReferenceField— связь с другой сущностью.
Нужна помощь с Битрикс?
Связь между сущностями
<?php
use Bitrix\Main\Entity\ReferenceField;
use Bitrix\Main\Entity\Query\Join;
use Bitrix\Main\UserTable;
public static function getMap(): array
{
return [
// ... остальные поля ...
new ReferenceField(
'ASSIGNED_USER',
UserTable::class,
Join::on('this.ASSIGNED_USER_ID', 'ref.ID')
),
];
}
<?php
$tasks = TaskTable::getList([
'select' => ['ID', 'TITLE', 'USER_NAME' => 'ASSIGNED_USER.NAME'],
]);
Описанная один раз связь позволяет выбирать поля связанной таблицы прямо в фильтре и выборке — без ручного построения JOIN и без отдельного запроса на каждую связанную запись.
Валидация полей
<?php
new StringField('TITLE', [
'required' => true,
'validation' => function () {
return [
new \Bitrix\Main\Entity\Validator\Length(1, 255),
];
},
]);
Валидация на уровне карты полей срабатывает при каждом
add() и update() — ошибка не даёт записи
сохраниться и возвращается в объекте результата, что избавляет
от необходимости дублировать те же проверки вручную перед каждым
вызовом.
Создание и обновление записи
<?php
$result = TaskTable::add([
'TITLE' => 'Проверить остатки склада',
'STATUS' => 0,
]);
if ($result->isSuccess()) {
$newId = $result->getId();
} else {
foreach ($result->getErrorMessages() as $message) {
echo $message . PHP_EOL;
}
}
Обязательная установка таблицы: install/db/install.php
ORM-модель описывает структуру для чтения и записи, но не создаёт
саму таблицу в базе — SQL для создания таблицы пишется отдельно
в обработчике установки модуля. Расхождение между картой полей
в getMap() и реальной структурой таблицы в базе
приводит к ошибкам SQL при первой же попытке обратиться
к отсутствующему столбцу.
Частые ошибки
- Карта полей не совпадает с реальной структурой таблицы. Ошибка SQL при обращении к полю, которого нет в базе, или наоборот.
- DatetimeField получает строку вместо объекта DateTime. Тот же класс, что и в остальном D7 API — строка не подходит.
- Связь описана, но не используется в select. Разработчик вручную дублирует запрос к связанной таблице, хотя ORM могла бы сделать это одним JOIN.
Итог
ORM-модель на D7 описывается через DataManager
с явной картой типизированных полей — это даёт валидацию, удобные
связи между таблицами и единый интерфейс запросов, но требует
ручной синхронизации карты полей с реальной структурой таблицы,
создаваемой отдельно при установке модуля.
