Yii2. Связанные данные
18.03.2019
Теги: Web-разработка • Yii2 • БазаДанных • Теория • Фреймворк • ШаблонСайта
Помимо работы с отдельными таблицами баз данных, ActiveRecord
также имеет возможность объединять связные данные, что делает их доступными для получения через основные объекты данных. Например, раздел каталога связан с товарами, которые в нем размещены. С помощью объявления этой связи можно получить доступ к информации о товарах категории с помощью выражения $category->products
.
-- Таблица `category` CREATE TABLE `category` ( `id` int(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'Первичный ключ', `parent_id` int(10) NOT NULL DEFAULT '0' COMMENT 'Родительская категория', `name` varchar(100) NOT NULL COMMENT 'Название категории', `sortorder` tinyint(3) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Порядок сортировки' ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `category` (`id`, `parent_id`, `name`, `sortorder`) VALUES (1, 0, 'Первая категория', 1), (2, 0, 'Вторая категория', 2), (3, 0, 'Третья категория', 3), (4, 0, 'Четвертая категрия', 4), (5, 1, 'Дочерняя категория', 1); -- Таблица `product` CREATE TABLE `product` ( `id` int(11) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'Первичный ключ', `category_id` int(10) NOT NULL DEFAULT '0' COMMENT 'Родительская категория', `name` varchar(200) NOT NULL COMMENT 'Название товара', `sortorder` tinyint(3) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Порядок сортировки' ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `product` (`id`, `category_id`, `name`, `sortorder`) VALUES (1, 1, 'Первый товар', 1), (2, 1, 'Второй товар', 2), (3, 2, 'Первый товар', 1), (4, 2, 'Второй товар', 2), (5, 5, 'Пятый товар', 1), (6, 5, 'Шестой товар', 2);
Объявляем связи в кассах моделей Category
и Product
:
<?php /* * Файл models/Category.php */ namespace app\models; use yii\db\ActiveRecord; class Category extends ActiveRecord { public function getProducts() { // связь таблицы БД `category` с таблицей `product` return $this->hasMany(Product::className(), ['category_id' => 'id']); } public function getParent() { // связь таблицы БД `category` с таблицей `category` return $this->hasOne(self::className(), ['id' => 'parent_id']); } }
<?php /* * Файл models/Product.php */ namespace app\models; use yii\db\ActiveRecord; class Product extends ActiveRecord { public function getCategory() { // связь таблицы БД `product` с таблицей `category` return $this->hasOne(Category::className(), ['id' => 'category_id']); } }
В контроллере получаем данные о каком-то товаре и о какой-то категории:
<?php namespace app\controllers; use yii\web\Controller; use app\models\Category; use app\models\Product; class CatalogController extends Controller { public function actionCategory() { // получаем информацию о категории с идентификатором 5 $category = Category::findOne(5); return $this->render('category', ['category' => $category]); } public function actionProduct() { // получаем информацию о товаре с идентификатором 2 $product = Product::findOne(2); return $this->render('product', ['product' => $product]); } }
Теперь в view-шаблоне views/catalog/category.php
мы можем получить не только информацию о категории:
<?php use yii\helpers\Html; ?> <div class="catalog-category"> <h1><?= Html::encode($category->name); ?></h1> </div>
SELECT * FROM `category` WHERE `id` = 5
Но и получить информацию о товарах категории и данные о родительской категории:
<?php use yii\helpers\Html; ?> <div class="catalog-category"> <h1><?= Html::encode($category->name); ?></h1> <?php $products = $category->products; /* товары категории */ ?> <?php if (!empty($products)): ?> <ul> <?php foreach ($products as $product): ?> <li><?= Html::encode($product->name); ?></li> <?php endforeach; ?> </ul> <?php else: ?> <p>Нет товаров в этой категории</p> <?php endif; ?> <?php $parent = $category->parent; /* родительская категория */ ?> <?php if (!empty($parent)): ?> <p>Родительская категория: <?= Html::encode($parent->name); ?></p> <?php endif; ?> </div>
SELECT * FROM `category` WHERE `id` = 5 -- дополнительный запрос после $products = $category->products; SELECT * FROM `product` WHERE `category_id` = 5 -- дополнительный запрос после $parent = $category->parent; SELECT * FROM `category` WHERE `id` = 1
Аналогично, в view-шаблоне views/catalog/product.php
можем получить не только информацию о товаре:
<?php use yii\helpers\Html; ?> <div class="catalog-product"> <h1><?= Html::encode($product->name); ?></h1> </div>
SELECT * FROM `product` WHERE `id` = 2
Но и получить информацию о родительской категории товара. А потом получить информацию о других товарах в родительской категории:
<?php use yii\helpers\Html; ?> <div class="catalog-product"> <h1><?= Html::encode($product->name); ?></h1> <?php $category = $product->category; /* родительская категория */ ?> <?php if (!empty($category)): ?> <p>Родительская категория: <?= Html::encode($category->name); ?></p> <?php $products = $category->products; /* другие товары в родительской категории */ ?> <?php if (!empty($products)): ?> <ul> <?php foreach ($products as $item): ?> <li><?= Html::encode($item->name); ?></li> <?php endforeach; ?> </ul> <?php endif; ?> <?php endif; ?> </div>
SELECT * FROM `product` WHERE `id` = 2 -- дополнительный запрос после $category = $product->category; SELECT * FROM `category` WHERE `id` = 1 -- дополнительный запрос после $products = $category->products; SELECT * FROM `product` WHERE `category_id` = 1
Поиск: Web-разработка • Yii2 • База данных • Фреймворк • Шаблон сайта • Связанные данные • Модель • Model • hasOne • HasMany