Active Record
Active Record — способ работать с таблицей через класс: таблице соответствует класс модели, а каждой строке — его объект. Столбцы таблицы сами становятся свойствами объекта, поэтому SQL писать не нужно.
Класс модели
Модели лежат в папке models. Создайте вручную файл models/Post.php:
// models/Post.php
namespace app\models;
use yii\db\ActiveRecord;
class Post extends ActiveRecord
{
public static function tableName(): string
{
return 'post';
}
}Этого достаточно: Yii сам прочитает из базы список столбцов таблицы post. Метод tableName() называет таблицу; без него Yii возьмёт имя класса строчными буквами.
Создание записи
Модель вызывают из контроллера. Добавьте в PostController строку use app\models\Post; и действие:
// controllers/PostController.php
public function actionSeed(): string
{
$post = new Post();
$post->user_id = 1;
$post->title = 'Первая статья';
$post->body = 'Текст статьи';
$post->created_at = time();
$post->updated_at = time();
$post->save();
return "Создана статья номер {$post->id}";
}Откройте /post/seed — в таблице появится строка, а страница покажет её номер. После save() в свойстве id лежит идентификатор новой строки.
Чтение
$post = Post::findOne(5); // по первичному ключу
$post = Post::findOne(['slug' => 'first']); // по значению столбца
$posts = Post::find()->all(); // все записи
$count = Post::find()->count(); // количество записейfindOne() возвращает объект или null, если строки нет. find() начинает запрос, а all() выполняет его и возвращает массив объектов.
Теперь действия контроллера могут брать статьи из базы:
public function actionIndex(): string
{
return $this->render('index', ['posts' => Post::find()->all()]);
}
public function actionView(int $id): string
{
$post = Post::findOne($id);
if ($post === null) {
throw new NotFoundHttpException('Статья не найдена.');
}
return $this->render('view', ['post' => $post]);
}В шаблоне к столбцам обращаются как к свойствам: $post->title, $post->body. В шаблоне views/post/index.php из прошлой главы замените $post['title'] на $post->title.
Изменение
$post = Post::findOne(5);
$post->title = 'Новый заголовок';
$post->save();Тот же метод save() обновляет существующую строку. Yii отправит в базу только изменившиеся столбцы.
Удаление
$post = Post::findOne(5);
$post->delete();Строка с номером 5 исчезнет из таблицы.
Массовые операции
Когда объекты не нужны, строки меняют одним запросом:
Post::updateAll(['status' => 0], ['user_id' => 5]);
Post::deleteAll(['status' => 0]);Первый аргумент updateAll() — новые значения, второй — условие отбора.
Частая ошибка
Метод save() перед записью проверяет данные по правилам модели. Если проверка не прошла, он не бросает исключение, а возвращает false — и запись молча не сохраняется. Всегда проверяйте результат:
if (!$post->save()) {
Yii::error($post->errors);
}Ошибки проверки лежат в свойстве $post->errors.