Администрирование множественных связей между таблицами (multilink / relations)
Для организации множественных связей между материалами Нодуса есть решение. Но и без нодуса ТАО позволяют организовать множественную связь между материалами.
Вернемся к новостному сайту. Предположим, что кроме новостной ленты есть некий справочник тем: спорт, экономика, и т.д. Требуется организовать привязку новости к темам, т.е. каждая запись в таблице публикаций должна иметь привязку одновременно к нескольким записям из таблицы тем. Организация связей будет осуществляться через таблицу связей.
Алгоритм организации множественной связи (multilink)
1. В описание таблицы новостей добавляем новое поле (тип новости).Указываем ему тип multilink, а в items
указываем источник данных orm
. Описывать sqltype
не надо.
// News/config/fields.php return array( 'news' => array( ... 'type' => array( 'type' => 'multilink', 'items' => 'orm:news_types', 'caption' => 'Тип', 'tab' => 'common', ), ), );
2. Для хранения связей создаем таблицу с произвольным именем.
// News/config/fields.php ... 'news_types_ties' => array( 'new_id' => array( 'sqltype' => 'int index', ), 'type' => array( 'sqltype' => 'int index', ), ), ...
- new_id - поле имеет произвольное название. Здесь будет храниться id новости.
- type - имя поля должно совпадать с именем ранее созданного поля multilink.
3. Для таблицы связей необходимо создать маппер.
// News/lib/Mapper.php class Component_News_Mapper_Ties extends CMS_ORM_Mapper implements Core_ModuleInterface { public function setup() { return parent::setup() ->table('news_types_ties') ->classname('CMS.ORM.Entity'); } }
Зарегистрировать его в конфигурационных настройках компонента.
// News/config/component.php return array( 'orm' => array( ... 'news_types_ties' => 'Component.News.Mapper.Ties', ), ... );
4. В описании сущности (Entity), для которой добавлялось поле multilink, укажем маппер таблицы связей. Для этого необходимо воспользоваться методом multilinks()
.
// News/lib/Mapper.php class Component_News_New extends CMS_ORM_Entity implements Core_ModuleInterface { ... protected function multilinks() { return array('news_types_ties'); } }
Никакой дополнительной организации методов записи или удаления данных не требуется.
Организация множественной связи между материалами (relations)
Множественную связь можно реализовать еще проще, используя тип поля relations
.
При добавлении нового поля (тип новости), указываем ему тип relations
(также без описания sqltype), а в items
указываем источник данных orm или массив в формате CMS::items_for_select.
// News/config/fields.php return array( 'news' => array( ... 'type' => array( 'type' => 'relations', 'items' => 'orm:news_types', 'caption' => 'Тип', 'tab' => 'common', ), ), );
Больше ничего не требуется. Здесь связь между материалами осуществляется также через стороннюю таблицу связей. Только в этом случае, таблица связей создается автоматически (NameTable_NameField_relations) с полями item_id
, rel_id
.
В случае, если требуется создать таблицу или поля (или и то и другое) со своими именами, то для этого можно воспользоваться свойствами table_name, item_id_name, rel_id_name
. В которых указать имена таблицы и полей. Свойства описываются в том же поле.
// News/config/fields.php return array( 'news' => array( ... 'type' => array( 'type' => 'relations', 'table_name' => 'other_table_rel', 'item_id_name' => 'new_id', 'rel_id_name' =>'type_id', 'items' => 'orm:news_types', ... ), ), );
Данный тип имеет ряд ограничений:
- подходит преимущественно для небольших списков, т.к. нет средств для управления и поиска по очень большому списку.
- реализация типа построена на прямых MySQL-запросах в базу. Т.е., если БД реализована не на MySQL, то воспользоваться данным типом поля не получится, оно не будет работать.