Данный раздел рассказывает про метод linked()
и его псевдоним _*
.
Вызывается метод так:
d()->User->_groups;
//или
d()->User->linked('groups');
Метод, применённый к списку (объекту ActiveRecord) возвращает все объекты, которые связаны названием столбца с каждым из элементов текущего списка, будь то дочерние элементы или родительские.
Для объекта, содержащего список элементов, метод linked
, который ищет дочерние элементы, вернёт список всех дочерних элементов для каждого объекта в текущем списке.
Для объекта, содержащего список элементов, метод linked
, который ищет родительские элементы, вернёт список всех родительских элементов для каждого объекта в текущем списке.
Метод linked
всегда возвращает объект ActiveRecord
. В случае, когда связей не найдено, возвращается пустая строка.
В этом плане метод схож с объектом jQuery, который всегда возвращает массив (даже если элемент один), и работает тоже с массивом.
В данном случае массивом всегда служит объект ActiveRecord, который привязан к списку объектов. К нему по прежнему можно применять фильтрацию, сортировку и т.д.
Для получения связей используется название столбца.
d()->Catalog->_products
будет искать таблицу products
со столбцом catalog_id
.d()->Product->_catalogs
будет искать таблицу catalogs
и столбец catalog_id
в текущей таблице.Приоритетом (когда можно найти и то и то) является список дочерних элементов.
Ниже представлены примеры использования этого метода, расположенные по порядку увеличения сложности примеров.
Уровень первый - разминка. Мы можем получать данные из связанных таблиц.
Мы имеем таблицы products
и catalogs
- каталоги и товары. Каждый товар может быть в каком-либо каталоге. Каталоги имеют структуру - один каталог может включать в себя несколько подкаталогов.
Получить все товары каталога с ID=4:
d()->prod_list = d()->Catalog(4)->_products;
Далее мы можем выводить товары как обычно:
<foreach prod_list>
<p>{.title}: {.cost} рублей.</p>
</foreach>
Даже если linked
возвращает массив, следует помнить, что любой объект ActiveRecord
- тоже массив, пусть и из одного элемента.
Вывести название каталога для товара с ID=3:
d()->Product(3)->_catalogs->title;
Получить каталог самого дорогого товара:
d()->Product->order_by('cost desc')->limit(1)->_catalogs;
Получить все подкаталоги каталога c ID=4:
d()->Catalog(4)->_catalogs;
Получить все товары каталога с ID=4, которые стоят больше 100 рублей:
d()->Catalog(4)->_products->where('cost > 100');
TODO: Полиморф
Есть таблица users у каждого пользователя есть отец (father_id
). В таблице fathers есть столбец user_id
, указывающий на пользователя. Вывести отца пользователя с ID=4:
d()->User(4)->_fathers->_users;
//Альтернатива:
d()->User(4)->father->user;
В данной группе примеров рассматриваются задачи, когда мы обращаемся не к одному элементу, а к группе: товаров или каталогов, пользователей или документов. При этом синтаксис остаётся тем же.
Пример тот же. Данные те же. Условия усложнены:
Получить все подкаталоги каталога с ID=4:
d()->Catalog(4)->_catalogs;
Получить все подкаталоги каталогов с ID=4 и ID=5:
d()->Catalog(array(4,5))->_catalogs;
Получить все товары всех подкаталогов каталога c ID=4:
d()->Catalog(4)->_catalogs->_products;
Получить все товары всех подкаталогов каталога c ID=4, 5 и 6:
d()->Catalog(array(4,5,6))->_catalogs->_products;
Получить все товары всех каталогов, отмеченных как новые is_new = 1
:
d()->Catalog->where('is_new = 1')->_products;
Получить все каталоги тех товаров, которые стоят больше 100 рублей:
d()->Product->where('cost > 100')->_catalogs;
Мы имеем список клиентов, каждый из которых имеет указанный город из таблицы cities
.
Получить все города, которые имеются в данном списке клиентов. Список клиентов ищется по полю name
, которое должно включать ключевые слова (поиск).
d()->Client->search('name', $_GET['s'])->_cities;
Пользователь выбрал (например, галочками) интересующие его города. Получить всех клиентов, которые имеются в массиве городов
// URL страницы выглядит так:
// http://site/clients/?cities_list[]=3&cities_list[]=34&cities_list[]=37&cities_list[]=71
d()->City($_GET['cities_list'])->_clients;
Есть таблица брендов. У каждого товара есть указанный бренд (производитель).
Получить список всех товаров каталога с ID=3. Над списком товаров вывести список брендов, которые присутствуют в данном списке:
d()->products = d()->Catalog(3)->_products;
d()->brands = d()->products->_brands;
Получить список всех товаров каталога с ID=3 и брендом с ID=7. Над списком товаров вывести список брендов, которые присутствуют в каталоге:
d()->products = d()->Catalog(3)->_products->where('brand_id = ?', 7);
d()->brands=d()->Catalog(3)->_products->_brands;
Получить список каталогов, в которых есть товары с брендом "Apple":
d()->Brand->where('title = ?', "Apple")->_products->_catalogs;
Получить список всех брендов, которые присутствуют во всех каталогах:
d()->Catalog->_products->_brands;
У нас есть таблица с клиентами. У каждого клиента есть город, у каждого города есть регион. У клиента есть несколько сотрудников (employees
). У сотрудника есть несколько фотографий. Каждая фотография может иметь несколько тегов (пометок).
Вывести все теги фотографий тех сотрудников фирм, которые работают в региона с ID=3;
d()->Region(3)->_cities->_clients->_employees->_photos->_tags;
У нас есть таблица с клиентами (companies). У каждого клиента есть ряд сотрудников (employees), каждому из которых можно указать город и привязать несколько фотографий. У каждого клиента есть пользователь - автор (user).
Вывести все фотографии сотрудников из региона с ID=4:
d()->Region(4)->_cities->_employees->_photos;
Вывести список пользователей, которые управляют клиентами, сотрудники которых из городов региона с ID=4:
d()->Region(4)->_cities->_employees->_clients->_users;
TODO: Полиморф
Есть таблица users у каждого пользователя есть отец (father_id
). В таблице fathers есть столбец user_id
, указывающий на пользователя. Вывести детей пользователя с ID=4:
d()->User(4)->_fathers->_users;//Шозана?
Примеры этого раздела используют связь many-to-many, когда товар может быть привязан к нескольким категориям, у объявления несколько авторов, несколько пользователей в одной группе. В предыдущих примерах были неявные примеры использования many-to-many.
Документы пользователи права запись и чтение
Документы пользователи права запись и чтение в отдельной таблоице в том числе кто добавил
Документы пользователи права запись и чтение в отдельной таблоице в том числе кто добавил история изменения доступов, некотрые кативны некоторые нет
TODO: Полиморфы
У нас есть таблица товаров products. Есть рекомендуемые аксессуары, которые тоже находятся в таблице products. Есть таблица accessories_to_products
. В каждой строке таблицы аксессуаров есть строка product_id
, указывающая на товар. Получить список аксессуаров товара c ID=4:
d()->Good(4)->_accessories_to_goods->_accessories->_goods;
many_to_many
, many-to-many
to many-to-many
.
Плюс. Типы прав (админ и т.д.)
Несколько строк
Документ в нескольких разделах одновременно. Вывести документы раздела, к которым есть доступ (группы, права).
"Пользователь может состоять в одной или нескольких группах, группа может иметь доступы разного уровня к одному или несколкьим документами, пользователь может иметь уровень разного доступа к одному или нескольким документами пользователь может быть администратором группы", показать все документы к которым имеет доступ пользователь, включая его документы и документы всех пользователей, всех групп, админом которых он является, с определенным уровнем доступа
Товары и каталоги. Всё находится в одной таблице (каталог можно купить).
Друзьяшки!
Список похожих товаров.
Список аксессуаров (привязан к каталогу и товару). И обратно - получить список товаров, для которого товар - аксессуар.
Список партнёров/торговых точек/компаний в группе компаний.
И обратно - получить родительскую компанию.
Вывести регион, в котором менеджеры меньше всего заполняют теги фотографий сотрудников.
Таск менеджер. Таски могут иметь большую вложенность, ограниченную только конфигом. У каждого таска есть автор, есть ответственные за выполнение которые могут менять статус. У каждого юзера есть руководитель кроме генерального. Каждый руководитель должен видеть таски подчиненных, и, опционально, всех подчиненных его подчиненных и т.п. структура компании тоже может быть сильно вложенной еще есть юзеры-партнеры которые вне иерархии, а аткже у тасков могут быть наблюдатели вообще любые