РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
339 of 1392 menu

Событие replicating

Событие replicating вызывается в момент, когда модель Eloquent клонируется с помощью метода replicate. Это событие позволяет модифицировать данные перед созданием копии, например, очищать определённые поля или устанавливать новые значения. Событие срабатывает до того, как будет создан новый экземпляр модели. Оно даёт возможность контролировать процесс копирования и изменять атрибуты будущей копии.

Синтаксис

<?php Model::replicating(function($model) { // Логика перед копированием }); ?>

Событие регистрируется в модели с помощью свойства $dispatchesEvents или через метод booted. Коллбэк получает текущий экземпляр модели и может изменять его атрибуты перед созданием копии.

Пример через свойство $dispatchesEvents

Давайте создадим модель Post и настроим событие replicating, которое будет очищать поле slug перед копированием:

<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use App\Events\ReplicatingPost; class Post extends Model { protected $dispatchesEvents = [ 'replicating' => ReplicatingPost::class, ]; } ?>

Теперь создадим обработчик события, который будет очищать поле slug и устанавливать новый заголовок:

<?php namespace App\Events; use App\Models\Post; class ReplicatingPost { public function handle(Post $post) { $post->slug = null; $post->title = $post->title . ' (Copy)'; } } ?>

Теперь при копировании записи поле slug будет пустым, а в заголовок добавится суффикс:

<?php use App\Models\Post; $post = Post::first(); $copy = $post->replicate(); echo $copy->slug; echo $copy->title; ?>

Результат выполнения кода:

"" "Original title (Copy)"

Пример через метод booted

Рассмотрим вариант регистрации события через метод booted внутри модели. Это удобно, когда нужно написать логику прямо в модели без создания отдельного класса-обработчика:

<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Product extends Model { protected static function booted() { static::replicating(function($model) { $model->sku = null; $model->stock = 0; }); } } ?>

Теперь при копировании товара поля sku и stock будут сброшены, чтобы новый товар имел уникальный артикул и нулевой остаток:

<?php use App\Models\Product; $product = Product::where('sku', 'ABC-123')->first(); $copy = $product->replicate(); echo $copy->sku; echo $copy->stock; echo $copy->name; ?>

Результат выполнения кода:

"" "0" "Original product name"

Пример с обработкой связей

Событие replicating также позволяет управлять копированием связанных данных. Давайте настроим модель Category, которая имеет связь с товарами, и при копировании категории будем очищать поле parent_id:

<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Category extends Model { protected static function booted() { static::replicating(function($category) { $category->parent_id = null; $category->slug = $category->slug . '-copy'; }); } public function products() { return $this->hasMany(Product::class); } } ?>

Теперь при копировании категории поле parent_id будет сброшено, а в slug добавится суффикс:

<?php use App\Models\Category; $category = Category::where('slug', 'electronics')->first(); $copy = $category->replicate(); echo $copy->parent_id; echo $copy->slug; echo $copy->name; ?>

Результат выполнения кода:

"" "electronics-copy" "Electronics"

Пример с условной логикой

В обработчике события можно использовать условную логику, чтобы по-разному обрабатывать копирование в зависимости от состояния модели. Например, для архивных записей мы можем сбрасывать больше полей:

<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Article extends Model { protected static function booted() { static::replicating(function($article) { $article->slug = null; if ($article->status === 'archived') { $article->status = 'draft'; $article->views = 0; } }); } } ?>

Теперь при копировании архивной статьи статус будет меняться на черновик, а счётчик просмотров обнуляться:

<?php use App\Models\Article; $article = Article::where('status', 'archived')->first(); $copy = $article->replicate(); echo $copy->status; echo $copy->views; echo $copy->title; ?>

Результат выполнения кода:

"draft" "0" "Archived article title"

Смотрите также

  • метод replicate,
    который создаёт копию модели
  • событие creating,
    которое срабатывает перед созданием записи
  • событие saving,
    которое срабатывает перед сохранением модели
  • метод save,
    который сохраняет модель в базу данных
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить