Событие deleting
Событие deleting в Laravel срабатывает непосредственно перед удалением модели из базы данных. Оно относится к модели Eloquent и является частью жизненного цикла модели. В обработчике события можно выполнить проверки, логирование, каскадное удаление связанных записей или даже отменить удаление, вернув false. Если обработчик возвращает false, операция удаления не выполняется.
Событие deleting можно использовать двумя способами: через наблюдатели (observers) или через замыкания в модели. Оно не принимает параметров, но предоставляет доступ к текущей модели через контекст.
Синтаксис
<?php
// В модели
class Article extends Model
{
protected static function booted(): void
{
static::deleting(function (Article $article) {
// Действия до удаления
// Если вернуть false, удаление отменяется
});
}
}
?>
Или через наблюдатель:
<?php
class ArticleObserver
{
public function deleting(Article $article): void
{
// Действия до удаления модели
}
}
?>
Пример
Давайте создадим модель Post и добавим событие deleting, которое будет логировать удаление перед тем, как запись будет удалена из базы данных:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;
class Post extends Model
{
protected static function booted(): void
{
static::deleting(function (Post $post) {
Log::info('Deleting post with ID: ' . $post->id);
});
}
}
?>
Выполним удаление записи:
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function destroy(int $id): void
{
$post = Post::find($id);
if ($post) {
$post->delete();
}
}
}
?>
Результат выполнения кода:
"Deleting post with ID: 5"
"Post successfully deleted"
Пример
Давайте используем событие deleting для проверки, можно ли удалить запись. Если у поста есть комментарии, удаление будет отменено:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Post extends Model
{
public function comments(): HasMany
{
return $this->hasMany(Comment::class);
}
protected static function booted(): void
{
static::deleting(function (Post $post) {
if ($post->comments()->count() > 0) {
return false;
}
});
}
}
?>
Выполним удаление поста с комментариями:
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function destroy(int $id): void
{
$post = Post::find($id);
if ($post) {
$res = $post->delete();
var_dump($res);
}
}
}
?>
Результат выполнения кода:
"false"
"Post not deleted due to existing comments"
Пример
Давайте используем наблюдатель для события deleting и выполним каскадное удаление связанных записей перед удалением основной модели:
<?php
namespace App\Observers;
use App\Models\Post;
use App\Models\Comment;
class PostObserver
{
public function deleting(Post $post): void
{
$post->comments()->delete();
}
}
?>
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Post extends Model
{
public function comments(): HasMany
{
return $this->hasMany(Comment::class);
}
}
?>
<?php
namespace App\Providers;
use App\Models\Post;
use App\Observers\PostObserver;
use Illuminate\Support\ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
public function boot(): void
{
Post::observe(PostObserver::class);
}
}
?>
Выполним удаление поста и его комментариев:
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use App\Models\Comment;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function destroy(int $id): void
{
$post = Post::find($id);
if ($post) {
$commentCountBefore = Comment::count();
$post->delete();
$commentCountAfter = Comment::count();
echo "Comments before: " . $commentCountBefore . "\n";
echo "Comments after: " . $commentCountAfter . "\n";
}
}
}
?>
Результат выполнения кода:
"Comments before: 10"
"Comments after: 0"
Смотрите также
-
событие
deleted,
которое срабатывает после удаления модели -
событие
forceDeleting,
которое срабатывает перед принудительным удалением -
событие
restoring,
которое срабатывает перед восстановлением модели -
событие
trashed,
которое срабатывает после мягкого удаления