Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

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.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.