← Назад к вопросам

Что делает save() в Active Record Yii2?

1.7 Middle🔥 201 комментариев
#Базы данных и SQL

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Метод save() в Active Record Yii2

Метод save() в Active Record Yii2 — это ключевой метод для сохранения данных модели в базу данных. Он выполняет валидацию данных и последующую вставку (INSERT) или обновление (UPDATE) записи в таблице БД, в зависимости от состояния модели. Это центральный механизм для работы с данными в Yii2, инкапсулирующий логику сохранения с учётом бизнес-правил.

Основная логика работы

Метод save() вызывает внутренний метод insert() или update(), основываясь на значении свойства $isNewRecord. Если модель новая (например, создана через new User()), выполняется INSERT. Если модель была загружена из БД (например, через User::findOne(1)), выполняется UPDATE. Ключевые этапы:

  1. Валидация данных: Если включена валидация (по умолчанию true), вызывается метод validate(). Все правила из rules() проверяются. При ошибках сохранение прерывается.
  2. События: Запускаются события Active Record, такие как beforeSave, afterSave, что позволяет встраивать кастомную логику.
  3. Сохранение в БД: Выполняется SQL-запрос (INSERT/UPDATE) с данными атрибутов модели.
  4. Очистка ошибок: После успешного сохранения, ошибки валидации сбрасываются.

Пример базового использования:

$user = new User();
$user->username = 'john_doe';
$user->email = 'john@example.com';
if ($user->save()) {
    echo "Пользователь сохранён с ID: " . $user->id;
} else {
    echo "Ошибки: " . print_r($user->errors, true);
}

Важные аспекты и параметры

  • Параметр $runValidation: По умолчанию true. Если установить в false, валидация пропускается — полезно для быстрого сохранения без проверок, но требует осторожности.
    $user->save(false); // Сохранение без валидации
    
  • Параметр $attributeNames: Позволяет указать массив атрибутов для сохранения, что полезно для частичного обновления.
    $user->save(['username', 'email']); // Сохраняются только эти поля
    
  • Оптимизация: При обновлении изменяются только модифицированные атрибуты, что снижает нагрузку на БД.
  • Транзакции: Для сложных операций рекомендуется оборачивать save() в транзакции:
    $transaction = Yii::$app->db->beginTransaction();
    try {
        if ($user->save()) {
            $transaction->commit();
        }
    } catch (\Exception $e) {
        $transaction->rollBack();
        throw $e;
    }
    

Обработка ошибок и события

При неудаче save() возвращает false. Ошибки можно получить через $model->errors. События позволяют добавлять логику:

class User extends \yii\db\ActiveRecord
{
    public function beforeSave($insert)
    {
        if (parent::beforeSave($insert)) {
            if ($insert) {
                $this->created_at = time(); // Логика для новой записи
            }
            $this->updated_at = time(); // Обновление метки времени
            return true;
        }
        return false;
    }
}

Отличия от update() и insert()

  • save() — универсальный метод, автоматически выбирающий операцию.
  • update() и insert() — низкоуровневые методы, выполняющие конкретные SQL-запросы без автоматической валидации (если не вызваны явно).

Практические рекомендации

  • Всегда проверяйте возвращаемое значение save() для обработки ошибок.
  • Используйте валидацию для обеспечения целостности данных.
  • Для массового обновления применяйте updateAll(), чтобы избежать накладных расходов на валидацию и события.
  • Учитывайте, что save() может быть переопределён в наследниках для кастомизации.

В итоге, save() — это мощный инструмент, сочетающий удобство с гибкостью, но требующий понимания его внутренней работы для эффективного использования в production-средах.

Что делает save() в Active Record Yii2? | PrepBro