От автора: приветствую вас, друзья. Итак, мы продолжаем цикл статей, посвященных знакомству с фреймворком Yii. И в этой статье мы продолжим изучение компонента Yii2 модели. В частности, мы узнаем, что такое связанные модели и как осуществляются связи моделей.
Итак, мы продолжаем знакомство с моделями. Напомню, в предыдущей статье мы с вами создали первую модель для работы со статьями, настроили подключение к БД и получили массив статей в виде массива объектов. Используя метод render() контроллера, мы передали полученные данные в представление. Теперь очередь за малым — нужно вывести эти данные. Здесь все просто, достаточно запустить цикл foreach и пройтись по массиву статей.
1 2 3 4 5 6 7 8 9 10 11 |
<h1>Список статей</h1> <?php foreach($posts as $post): ?> <div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title"><?= $post->title ?></h3> </div> <div class="panel-body"> <?= $post->excerpt ?> </div> </div> <?php endforeach; ?> |
В результате мы должны получить примерно такую картину:
Мы без особых проблем получили список статей. Но, как вы помните, каждая статья принадлежит к определенной категории. Давайте создадим такую таблицу и заполним ее тестовыми данными.
1 2 3 4 5 6 7 |
CREATE TABLE IF NOT EXISTS `category` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `keywords` varchar(255) DEFAULT NULL, `description` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
Как вы помните, поле category_id таблицы post ссылает на поле id таблицы category и указывает на принадлежность статьи к определенной категории. Так вот, как бы нам, доставая статьи, заодно достать и категории, к которым относятся данные статьи? Проще говоря, нужно выполнить что-то вроде объединения таблиц (JOIN).
Для решения данной задачи во фреймворке предусмотрены связи. Фактически это аналог тех самых связей SQL, которые мы знаем под названиями один-к-одному, один-ко-многим и т.д. Итак, для реализации связи нам потребуется создать для начала еще одну model, которая будет работать с категориями.
1 2 3 4 5 6 7 8 |
namespace app\models; use yii\db\ActiveRecord; class Category extends ActiveRecord { } |
Ну а теперь необходимо связать модели, используя метод геттер. В классе Post создадим следующий метод:
1 2 3 4 5 6 7 8 |
class Post extends ActiveRecord { public function getCategory(){ return $this->hasOne(Category::className(), ['id' => 'category_id']); } } |
Давайте разберем этот метод. Начнем с названия — getCategory. Фактически это имя связи, которое скажет нам, что метод устанавливает связь с Category. Метод обращается к методу hasOne, который описывает связь один-к-одному. Первым параметром методу hasOne() мы должны передать имя класса модели, с которой необходимо установить связь. Делать это рекомендуется именно так, как мы прописали в коде НазваниеМодели::className(). Вторым параметром мы передаем массив, где ключом выступает поле таблицы, с которой мы связываемся, а значением — поле текущей таблицы. В нашем примере ключ id — это поле category
.id
, значение — post
.category_id
.
Как теперь получить доступ к связанным данным? Проще простого. После определения связи, нам доступно виртуальное свойство с именем геттера связи. Поскольку геттер мы назвали getCategory, виртуальное свойство будет называться category. Почему виртуальное? Потому что в объектах массива $posts у нас сейчас не будет такого свойства. Тем не менее, если мы обратимся сейчас в цикле к этому свойству — мы получим связанные данные. Давайте попробуем сделать это в представлении.
1 |
<?php var_dump($post->category) ?> |
В результате мы увидим, что в данном свойстве хранится объект Category.
Осталось лишь обратиться к нужным свойствам данного объекта. Например, выведем наименование категории, которой принадлежит тот или иной пост.
1 |
<p>Категория: <?= $post->category->name ?></p> |
Как видим, связи работают и очень удобны в использовании. В контроллере мы не изменили ни единой строчки кода, но получили дополнительные связанные данные. На этом мы, пожалуй, пока остановимся. Больше о фреймворке вы можете узнать из наших бесплатных или платных уроков. Также создание простейшего блога на Yii2 можно посмотреть в этом цикле уроков.