Дескриптор атрибута объекта (или дескриптор поля, если хотите) – это хеш-структура, описывающая полный набор параметров и свойств, описывающих поле объекта, его внешний вид в форме редактирования объекта и связь с определенным полем в БД (для полей, описанных в required_properties).
Полный массив атрибутов возвращает метод structure любого Contenido-объекта. Собирается этот список из полей, описанных в методах required_properties дескриптора таблицы и extra_properties объекта Contenido. Причем, атрибуты, описанные в extra_properties, накладываются на список атрибутов, описанных в required_properties, переписывая свойства основных полей. Сопоставление ведется по значению attr – названию атрибута, на основе которого строится соответствующий метод.
Пример описания списка основных атрибутов:
sub required_properties
{
my $self = shift;
my @parent_properties = $self->SUPER::required_properties;
return (
@parent_properties,
{
'attr' => 'uid',
'type' => 'integer',
'rusname' => 'Идентификатор пользователя',
'db_field' => 'uid',
'db_type' => 'integer',
'db_opts' => "not null default 0",
},
{
'attr' => 'ext_id',
'type' => 'integer',
'rusname' => 'Внешний ID новости',
'db_field' => 'ext_id',
'db_type' => 'integer',
'db_opts' => "default 0",
},
{
'attr' => 'subscribe',
'type' => 'checkbox',
'rusname' => 'Включить в рассылку?',
'db_field' => 'subscribe',
'db_type' => 'integer',
'db_opts' => "not null default 0",
'default' => 0,
},
{
'attr' => 'votes',
'type' => 'integer',
'rusname' => 'Кол-во голосов',
'db_field' => 'votes',
'db_type' => 'integer',
'default' => 0,
},
{
'attr' => 'value',
'type' => 'integer',
'rusname' => 'Сумма голосов',
'db_field' => 'value',
'db_type' => 'integer',
'default' => 0,
},
{
'attr' => 'rating',
'type' => 'integer',
'rusname' => 'Рейтинг',
'db_field' => 'rating',
'db_type' => 'integer',
'default' => 0,
},
);
}
Пример описания экстра-полей в объекте с переопределением:
sub extra_properties
{
return (
{ 'attr' => 'dtime', 'type' => 'datetime', 'rusname' => 'Дата', },
{ 'attr' => 'uid', 'type' => 'pickup', 'rusname' => 'Пользователь',
lookup_opts => { class => 'users::Profile', search_by => 'name' },
},
{ 'attr' => 'abstr', 'type' => 'text', 'rusname' => 'Аннотация', rows => 5 },
{ 'attr' => 'body', 'type' => 'wysiwyg', 'rusname' => 'Полный текст документа', rows => 45 },
{ 'attr' => 'url', 'type' => 'url', 'rusname' => 'Ссылка на оригинал' },
{ 'attr' => 'source_name', 'type' => 'string', 'rusname' => 'Источник / исходящие данные' },
{ 'attr' => 'source_url', 'type' => 'string', 'rusname' => 'URL источника' },
{ 'attr' => 'icon', 'type' => 'image', 'rusname' => 'Иконка', preview => ['240x240'], crop => ['150x150'] },
{ 'attr' => 'pictures', 'type' => 'images', 'rusname' => 'Список изображений', preview => ['240x240'], crop => ['150x150'] },
)
}
В данном примере для атрибута dtime (унаследован от SQL::DocumentTable) переопределена подпись (rusname) поля в форме редактирования. А для атрибута uid переопределен тип и добавлена структура, необходимая для обработчика данного типа (pickup).
Итоговая структура, возвращаемая методом structure для поля dtime, будет выглядеть так:
{
'attr' => 'dtime',
'type' => 'datetime',
'rusname' => 'Дата',
'column' => 1,
'db_field' => 'dtime',
'db_type' => 'timestamp',
'db_opts' => 'not null default now()',
'default' => 'CURRENT_TIMESTAMP',
},
Итоговая структура, возвращаемая методом structure для поля uid, будет выглядеть так:
{
'attr' => 'uid',
'type' => 'pickup',
'rusname' => 'Идентификатор пользователя',
'lookup_opts' => {
'class' => 'users::Profile',
'search_by' => 'name',
},
'db_field' => 'uid',
'db_type' => 'integer',
'db_opts' => "not null default 0",
},
Все атрибуты, возвращаемые методом extra_properties и не имеющие соответствия среди основных полей, добавляются в конец списка метода structure. Их содержимое при сохранении объекта в БД собирается в единую структуру, сериализуется (в момент написания статьи методом сериализации выбран json) и складывается в поле data.
При инициализации объекта из БД, происходит обратный процесс: десериализация и разбрасывание значений по атрибутам.
Общий вид описания атрибута
Параметры, участвующие в описании атрибута, по своей принадлежности разделяются на:
- параметры самого атрибута;
- параметры связи с базой данных;
- параметры, управлящие обработчиком типа;
- пользовательские параметры.
Попробуем расписать пулю на примере уже описанного uid:
{
## Описание атрибута
'attr' => 'uid', # название атрибута
'type' => 'pickup', # тип атрибута
'rusname' => 'Идентификатор пользователя', # название поля в админке
## Параметры связи с БД
'db_field' => 'uid', # название поля в БД
'db_type' => 'integer', # тип поля в БД
'db_opts' => "not null default 0", # опции поля в БД
'default' => 'NULL', # значение по умолчанию, подставляемое в SQL-запрос; также используется для формы редактирования некоторыми обработчиками типов
## Параметры, управляющие обработчиком
'lookup_opts' => { # параметры запроса к get_documents для поиска и подбора связанных документов
'class' => 'users::Profile',
'search_by' => 'name',
},
},
.
Типы данных
В дескрипторе атрибута поле type