Версия:

Описание профайла полей

В отличии от профайла класса, где настройки относятся к самому классу, тут настраивается поведение каждого его поля в отдельности. Сюда попадают во-первых, системные настройки, необходимые для работы ядра (например информация о типе поля и, если поле виртуальное (физически не располагается в этой таблице), то информация о связи с другими таблицами или из каких полей/строк его собрать. А во-вторых, настройки поведения, как для серверной части, так и для клиентских компонентов.

В описании будут встречаться виртуальные поля, то есть поля из других таблиц, со своим ключем. Например class (class_id). Мы не будем акцентировать, что физически храниться именно поле <что-то>_id, чтобы не писать везде одно и то же.

Поля

class_id. Системное поле, поле связи с классом.

column_name. Это системное имя поле и оно не должно изменяться после создания. Именно так поле называется в tables.json и в базе данных.

name. Это пользовательское наименование поля (user friendly). Эта надпись будет в таблицах и формах.

select_class. Необходим для клиентских компонентов для виртуальных полей (подключенных из других таблиц), чтобы выпадающие списки знали в какую таблицу. Как правило там нужно указать тоже что и в from_table. Если ничего не указано, то ядро может использовать from_table, однако эта опция появилась недавно и не тестировалась полноценно, так что если выпадающие списки не туда обращаются, просто укажите верный класс в этом поле.

parent_key. См. также описание parent_key в профайле самого класса. Позволяет указать, что по этому полю будет применена фильтрация данных в таблице, если эта таблица расположена внутри формы родительской сущности. Например в форме заказа (№15), можно разместить таблицу с позициями заказа и указать этой таблице, что parent_key это “order_id”, тогда будут выведены только позиции этого (15-го) заказа.

primary_key. Системное. Всегда id.

foreign_disable (foreign_table, foreign_key_str). Ядро может автоматически генерировать внешние ключи для полей ссылающихся на другие таблицы. Этот механизм был введен относительно недавно, и он по умолчанию создавал внешние ключи, но это можно было отключить параметром foreign_disable. Далее стало ясно, что лучше не создавать ключи для всех, а делать это точечно. Поэтому теперь этот параметр по умолчанию имеет значение true.

foreign_table, foreign_key_str - системные поля, куда вписывается определенные системой зависимости.

return_id, return_name, lov_return_to_column, select_search_columns. Поля для настройки редактора вида выпадающий список.

Запрос направляется в select_class и берет оттуда id и name. Однако это можно переопределить.

return_id. Можно указать чтобы из запрашиваемой таблицы возвращалось не id, а какое-нибудь другое поле. Это может быть полезно, если сам запрос переопределен и например делает группировку по какому-нибудь полю, тогда именно его имеет смысл брать как id для списка.

return_name. Это поле переопределяется чаще, чем return_id, так как даже если запрос идет в классический справочник, то не всегда из него нужен именно name. Например из справочника d_cities может потребоваться поле name_full (поле, например, содержит полный адрес города, с указанием страны и области).

lov_return_to_column. Определяет в какое поле подставить выбранное значение. Если, например, редактор типа “Выпадающий список” указан для поля city, то система по умолчанию, посмотрит, какой keyword у этого поля, то есть через какое поле осуществляется связь со справочником, и поняв что это city_id установит выбранное значение из списка именно туда. Но иногда требуется переопределить это поведение.

select_search_columns. Позволяет указать через запятую поля, по которым будет осуществляться поиск в справочнике (в выпадающем списке есть поле ввода для фильтрации значений). По умолчанию поиск идет по полю указанному в return_name.

select_autocomplete_columns. Используется при работе с дополняемым списком. Часто при заполнении справочника недостаточно просто указать одно поле, а нужно заполнить несколько. В этом случае системе нужно знать, какие еще поля требуется заполнить, чтобы добавление прошло успешно. Можно перечислить эти поля через запятую.

Я не уверен что этот механизм работает в текущей версии ядра.

sort_no. Важный параметр, определяет последовательность колонок в таблице. Менять его можно через контекстное меню в настройках полей класса или клиентского объекта “Set column position".

Имеется важная особенность, которую следует учитывать при сортировке. Поля, использующие другое поле как ключ связи (относится к виртуальным полям, которые подтягиваются из других таблиц посредствам JOIN, используя ключ указанный в “keyword”), должны располагаться после этого ключа.

Кроме этого, у вас могут быть поля, которые подключены через JOIN через несколько таблиц (у них прописан параметр “join_table”), такие поля должны располагаться после одного из (любого) виртуального поля, использующего ту таблицу, через которую осуществляется соединений. Если соединение осуществляется через несколько таблиц, то соответственно будет несколько полей, которые должны располагаться перед.

Думаю в дальнейшем ядро будет доработано и порядок JOIN будет определяться автоматически, но пока следует учитывать это ограничение.

type, field_length. Системные поля определяющие тип и длину поля так, как это необходимо СУБД. Они заполняются в tables.json и не правятся через интерфейс.

Если вы создали не с тем типом, то поле следует удалить из tables.json, синхронизировать и создать заново.

lov_columns. В настоящее время не используется.

filter_type (filter_type_id). Позволяет выбрать, какой тип фильтра должен быть у этого поля. Фильтры появляются в клиентском компоненте таблиц, если есть хотя бы одно поле, у котого выставлен тип фильтра. Если тип фильтра не выбран, то фильтра по этому полю не будет.

Фильтры выбираются исходя из типа поля. Это может быть диапазон чисел, даты, даты и времени, чекбокс, текст (строгое совпадение), текстLike (совпадение части строки), выпадающий список и выпадающий список с пустым значением.

Выпадающий список работает на основе существующих данных, то есть там будут только те уникальные значения, которые встречаются в данных этой таблицы.

Есть желание сделать возможность переключения режима, чтобы для полей относящихся к справочникам, например Статус, запрос был именно к справочнику, а не запрос данных с группировкой по этому полю. Но это не редко нужно.

Кроме этого в одном проекте, еще на первой версии ядра, эти фильтры доработаны (по мере необходимости будет перенесено):

Список предоставляет не только уникальные значение но и подсчет количества вхождений, например Статус: Создан(5), В работе (8)

А также есть возможность указать фильтр опираясь на данные в отдельной таблице со связью один ко многим, например виртуальное поле Исполнители, может обращаться к таблице ИсполнителиЗаявки и выдавать уникальные значения оттуда.

Мультиселект. Позволяет выбрать несколько значений.

type_of_editor (type_of_editor_id). Схож с типом фильтров, но определяет какой редактор будет у этого поля для редактирования/создания. Используется в клиентских компонентах (формы, фреймы, таблицы). Может быть текстом, wysiwyg, textarea, числом, выпадающим списком, если это виртуальное поле подтягивающиеся из другой таблицы, чекбокс, дата, дата и время дни недели (не уверен что работает корректно), изображение (позволяет выбрать изображение с предпросмотром), файл (позволяет выбрать файл), телефон (не уверен что работает корректно), иконка (не знаю как работает).

Имеется возможность написать новые редакторы, а также можно на уровне конкретного клиентского объекта (его js файла) переопределить поведение и написать вообще что-нибудь кастомное.

quick_search_field. Галочка определяет, что по этому полю будет производится поиск при вводе текста в строку быстрого поиска в клиентском компоненте таблиц или при вызове метода search. По умолчанию установлена у поля id.

visible. Определяют видимость полей для клиентских компонентов. Если visible=false, то это, во-первых, будет отражено в профайле, а во-вторых, это поле не будет возвращено методом get.

Важно понимать, что это не влияет на операции add/modify, для них есть отдельные галочки.

required. Определяет что это поле обязательно для заполнения при добавлении записи. Это проверяется на бэкенде, а также клиентские компоненты форм, фреймов и таблиц подсвечивают эти поля звездочкой и при попытке сохранить без заполнения.

editable. По умолчанию = true. Определяет можно ли это поле редактировать (указывать при создании записи или изменять после). Проверяется на бэкенде, а клиентские компоненты выводят их либо с редактором, либо без.

Галочка определяет запрет (при editable=false) на редактирование для запросов с клиента, таким образом вы можете изменить это поле из других методов на стороне бэкенда. Это частая практика, когда поле нельзя изменять напрямую, но есть отдельный метод (например с ограниченным доступом) приводящим к его изменению, возможно с какими-нибудь проверками или сайд эффектами.

Для ограничения редактирования, в том числе, на стороне бэкенда существует галочка server_editable.

server_editable. Как указано выше (описания поля “editable”), ограничивает доступ редактирования (add/modify) для запросов из методов бэкэнда, а не с клиента.

insertable. По умолчанию = false. Галочка аналогична “editable”, но распространяется только на добавление. Чтобы запретить добавление, нужно чтобы обе галочки были false.

По аналогии с “editable”, распространяется на запросы с клиента.

server_insertable. Как указано выше (описания поля “insertable”), ограничивает доступ добавления для запросов из методов бэкэнда, а не с клиента.

updatable. По умолчанию = false. Галочка аналогична “editable”, но распространяется только на изменение. Чтобы запретить изменение, нужно чтобы обе галочки были false.

По аналогии с “editable”, распространяется на запросы с клиента.

server_updatable. Как указано выше (описания поля “updatable”), ограничивает доступ изменение для запросов из методов бэкэнда, а не с клиента.

queryable. Поля ограниченные этим параметром (queryable=false) не возвращаются в запросе getProfile и не возвращаются на клиент в методе “get”, однако, возвращаются в “get” в запросах из других методов на бэкенде.

На практике это используется только во внутреннем механизме динамических полей.

whereable. Позволяет запретить применение условий выборки по конкретному полю.

from_table, keyword, return_column. Используются только для полей is_virtual=true. Позволяют указать из какой таблицы, по какому ключу и какое поле вернуть, для полей подтягиваемых из других таблиц. Запрос формируется ядром с помощью JOIN. Заполняются в tables.json и не должны редактироваться через интерфейс.

Для соединений через несколько таблиц существует поле “join_table”, см. ниже.

keyword с подстановкой. Вроде сейчас не используется.

join_table. Позволяет сделать соединение через одну или несколько таблиц. В этом поле указывается, через какую таблицу соединить, при этом в from_table, как и в обычном случае, указывается какую таблицу надо присоединить.

Важно чтобы указанная в join_table таблица, была ранее подключена в другом поле. То есть сперва у вас идет поле без join_table, а просто с from_table/keyword/return_column, а уже после может быть поле с join_table/from_table/keyword/return_column, где join_table будет равно from_table предыдущего поря.

Если соединение идет через несколько таблиц, то каждая предыдущая должна быть предварительно также представлена.

Рассмотрим на примере. Таблица заказа, у него есть поле “пользователь”, из таблицы пользователей, и у пользователя есть поле “gender”, из таблицы гендеров. Мы хотим, чтобы в таблице заказов были все эти поля:

Мы добавляем user_id (физическое поле для связи)

Добавляем поле user_nickname, чтобы видеть кто это. is_virtual=true; from_table=”user”; keyword=”user_id”; return_column=”nickname”.

Добавляем поле user_gender. is_virtual=true; join_table=”user”; from_table=”gender”; keyword=”gender_id”; return_column=”name”.

Поле keyword для поля подключеного через одну или несколько таблиц указывается, как ключ связи, в предпоследней таблице, то есть в той, которая указана в join_table. На данном примере мы видим, что мы присоединяем таблицу “gender”, из таблицы “user”, а в ней именно “gender_id” позволяет соединиться с таблицей “gender”.

join_table_alias, join_table_by_alias. Используется, когда внешняя таблица подключается более одного раза для двух разных полей. join_table_alias используется для указания альяса подключаемой таблицы (указанной в from_table), а join_table_by_alias указывается для следующей подключаемой таблице, сообщая что для соединения нужно использовать именно “тот JOIN”, у которого альяс равен указанному.

Например в таблице order два поля supplier_id и customer_id, а я хочу подтянуть также nickname и пол для каждого. У меня будет:

Для supplier

Поле supplier_id, физическое.

Поле supplier_nickname. is_virtual=true; from_table=”user”; keyword=”supplier_id”; return_column=”nickname”. А также зададим ему алиас: join_table_alias=”user_supplier”.

Поле supplier_gender. is_virtual=true; join_table=”user”; from_table=”gender”; keyword=”gender_id”; return_column=”name”. А также зададим ему через какое именно соединение (так как будет два “join user”) нужно подключать эту таблицу: join_table_by_alias=”user_supplier”.

Теперь тоже самое для customer.

Поле customer_id, физическое.

Поле customer_nickname. is_virtual=true; from_table=”user”; keyword=”customer_id”; return_column=”nickname”. А также зададим ему алиас: join_table_alias=”user_customer”.

Поле customer_gender. is_virtual=true; join_table=”user”; from_table=”gender”; keyword=”gender_id”; return_column=”name”. А также зададим ему через какое именно соединение (так как у нас два “join user”) нужно подключать эту таблицу: join_table_by_alias=”user_customer”.

table_alias. Не используйте table_alias, это системное поле.

dynamic_field_id. Системное поле используется для динамических полей.

modify_in_ext_tbl, modify_in_ext_tbl_key. Используется для механизма динамических полей. Позволяет реализовать редактор данных хранящихся в другой таблице. Механизм, в принципе, можно использовать не только для динамических полей, но только если это понадобится и это потребует вникнуть в реализацию.

is_virtual. Всегда указывается для полей, которые подтягиваются из других таблиц (см. from_table/keyword/return_column), но может также использоваться и для других видов виртуальных полей, таких как CONCAT (см. concat_fields).

concat_fields. Позволяет указать через запятую или через пробел, что нужно сконкатинировать. Если система обнаружит хоть одну запятую, то она будет считать, что разделять надо по запятым, если нет, то по пробелу. Лучше используйте запятые.

Каждый элемент может быть просто строка или имя поля. Точнее так, если есть поле с таким именем, то будет подставлено оно, иначе будет подставлено как есть (конечно с экранированием). Если нужно указать пробел, то он тоже должен быть между запятыми. Например fio:

"fio" : {"type": "varchar", "length": "255", "concat_fields": "lastname, ,firstname, ,midname", "is_virtual": true, "name": "ФИО"},

А, например, для поля password мы просто выводим “*”:

"password": {"type": "varchar","length": "255", "concat_fields": "*", "name": "Пароль",  "is_virtual": true},

extraSQL. В поле concat_fields можно указать “extraSQL”. Тогда система позволит подставлять в это поле свой sql, однако он должен быть определен на этапе init метода класса. То есть его следует переопределить для класса и вписать туда extraSQL в “profile” соответствующего поля, а также указать от каких полей зависит этот sql (dependCols) чтобы система могла собирать необходимые join и корректно работать с кэш.

Это лучше посмотреть на примере:

export default class Order_ extends CoreClass {  
   private initSuper: (params) => Promise<IError>  
   constructor(params: IObj) {  
       super(params)

       this.initSuper = super.initPrototype  
   }

   /**  
    * Overriding the init method.  
    * Here we define extraSQL for the "from_user" field to concat fio or nickname,  
    * RU:  
    * Переопределение метода init.  
    * Здесь мы определяем extraSQL для полей "to_user" для конкатенации fio или nickname,  
    * @param params  
    */  
   async init(params): Promise<IAPIResponse> {

       const res: IAPIResponse = await this.initSuper(params)  
       if (res.code) return res

       const fromUserColProfile = this.class_fields_profile['from_user']  
       const toUserColProfile = this.class_fields_profile['to_user']

       if (fromUserColProfile) {

           fromUserColProfile.extraSQL =  
               `CASE  
                   WHEN \`user2\`.\`use_nickname\` = 1 THEN \`user2\`.\`nickname\`  
                   ELSE CONCAT_WS(' ', \`user2\`.\`lastname\`, \`user2\`.\`firstname\`, \`user2\`.\`midname\`)  
               END`

           fromUserColProfile.dependCols = [  
               'from_user_id', 'use_nickname'  
           ]  
       }

       if (toUserColProfile) {

           toUserColProfile.extraSQL =  
               `CASE  
                   WHEN \`user1\`.\`use_nickname\` = 1 THEN \`user1\`.\`nickname\`  
                   ELSE CONCAT_WS(' ', \`user1\`.\`lastname\`, \`user1\`.\`firstname\`, \`user1\`.\`midname\`)  
               END`

           toUserColProfile.dependCols = [  
               'to_user', 'use_nickname'  
           ]  
       }

       return res  
   }
}

Этот механизм позволяет работать с этим полем как если бы оно хранилось в базе физически (ну или было б сформировано во VIEW), как уже в конечных компонентах (таблицах/формах/фреймах), так и при получении и работе с данными в других методов на стороне бэкенда.

default_value. Позволяет указать значение по умолчанию для поля. То есть при создании записи, если значение для поля не передано, но у него указано default_value, то будет подставлено указанное значение.

Вы можете использовать это поле и для виртуальных полей, например чтобы указать значение по умолчанию для статуса (который берется из справочника статусов). Вместо того, чтобы указывать какое-то число для поля status_id, вы можете указать системное имя (в справочниках типа статус, мы всегда делаем поле “sysname”), то есть для виртуального поля “status_sysname”, мы можем указать default_value=”CREATED”, тогда при создании, система сама обратится в справочник статусов (тот что указан как from_table, для поля status_sysname), получит ID этого статуса и подставит его в поле status_id.

validation. Строка. Позволяет указать имя функции, которая будет проводить валидацию. Стандартные функции имеются в файле functions.ts в объекте validation (isDate, notNull, number, url, email). Но можно определить свою как метод класса (this.myValidateFn) и указать в validation “myValidateFn”.

Как ее написать, смотрите существующие примеры. Но помимо самой функции, следует написать пример и добавить его (не трогая CoreClass) в this.validationFormats.

number: {  
   format: '<число>',  
   example: '10'  
},

В самом классе написать this.validationFormats.myValidateFn = {format:’AABBCC’, example:’AABBCC’}.

Это требуется для того чтобы сообщение об ошибки валидации было наглядным.

Когда запись не проходит валидацию (по одному или нескольким полям), то метод (add/modify) вернет ошибку с объектом {message: ‘Одно или несколько полей имеет неверный формат’, fields: not_valid}, где not_valid - массив объектов вида {field: field, format: this.validationFormats[valFunc] || ‘’}.

get_formating, set_formating. Позволяет указать особую функцию для форматирования при получении и сохранении. Важно отметить, что такие функции применяются системой автоматически в зависимости от типа поля (например, дата переформатируется из формата MySQL в user friendly и обратно), но можно заменить стандартную обработку. Используется редко.

is_unique. Система следит, чтобы сочетание полей отмеченных этой галочкой было уникальным. Также можно включить дополнительное отслеживание на уровне СУБД - см. mysql_unique.

hint. Здесь можно указать текст подсказки, который будет показан при наведении на поле (колонку) в клиентских компонентах (таблицах/формах/фреймах). Может использоваться и в кастомных компонентах.

min_value, max_value, value_step. Определяет пределы и шаг для числовых полей, однако в текущей версии нигде не используется (почему то ни в таблицах, ни в формах/фреймах, ни на бэкэнде). При необходимости будет доработано.

min_datetime_value, max_datetime_value, default_datetime_value. Позволяет определить минимальные и максимальные границы для полей формата даты и даты/время, а также указать дефолтное значение. Реализовано в клиентском компоненте фреймов и позволяет использовать подстановки now (текущая дата и время) или now_date (текущая дата).

При необходимости могут быть доработаны прочие клиентские компоненты, а также реализована проверка на бэкенде.

calender_options. Позволяет указать кастомные настройки для календаря (компонент выбора даты и время). Документация здесь: https://flatpickr.js.org/options/ (версия может быть устаревшей).

is_inherit. Позволяет указать, что это поле наследуемое. Это значит, что если нет своего значения, то в это поле может быть возвращено значение этого же поля ближайшего родителя, у которого есть это значение. Это будет работать если для класса/клиентского объекта включен режим см. enableInheritValues.

is_class_field, is_co_field. Системные поля.

save_log, always_save_log. Отмечают поля, для которых необходимо вести историю изменений. См. /docs/gocore-v2.0/kak-razrabatyvat/sushchestvuyushchie-klassy-i-ih-metody/bazovyy-klass/metody-bazovogo-klassa/history.

Поля дополнительно отмеченные галочкой always_save_log, будут сохраняться не только когда они меняются, а при любом любых других отслеживаемых полей. Не факт, что это нужно в текущей реализации (раньше таким признаком отмечалось поле даты, сейчас дата и так логируется).

Чтобы механизм работал, нужно создать дополнительную таблицу для класса. См. описание механизма.

depend_column, is_depend_where_func. Используется для клиентского компонента фреймов. Позволяет указать, от какого поля зависит это поле (оно будет недоступно, пока не будет указано исходное). Также можно указать имя функции, которая позволит сформировать where, которое будет наложено на запрос для получения выпадающего списка этого поля (опираясь на данные, установленные в зависимом поле). Пример таких функций есть в frame_example.

frame_for_edit_values. Системное поле, позволят (для динамических полей) указать фрейм который будет открыт для редактирования значения.

Реализована поддержка в таблицах.

Возможно, можно будет использовать не только для динамических полей, но и для других, если хочется сделать кастомный редактор поля.