В настоящее время я работаю с прослушивателями событий Laravel в очереди на событие saving
модели Eloquent. В моем классе событий я установил общедоступное свойство, содержащее мою модель, к которой я затем могу получить доступ внутри объекта $event
в моем слушателе через $event->myModel
.
Метод handle()
моего слушателя сравнивает старые значения с новыми, поэтому я удалил Illuminate\Queue\SerializesModels
в своем классе событий. Это отлично работает, и теперь я могу сравнивать старые значения с новыми.
Проблема в тестировании. Я делаю тест, который проверяет, отличается ли старое и новое значение, которое я получаю в методе handle()
моего слушателя. Однако теперь $event->myModel->getOriginal()
возвращает пустой массив. Это происходит только при тестировании.
Это ошибка?
Я попытался установить public $originalModelProps
в своем классе событий, однако он возвращает пустое значение, когда вызывается метод handle() моего слушателя.
Я не использую Illuminate\Queue\SerializesModels
или какой-либо трейт/класс/интерфейс с именем SerializesModels
в своем коде.
События/Модели/MyModel/MyModelSavedEvent.php
<?php
namespace App\Events\Models\MyModel;
use App\Models\MyModel;
use Illuminate\Queue\SerializesModels;
class MyModelSavedEvent
{
/**
*
* @var \App\Models\MyModel
*/
public $myModel;
public $originalAccessLevelProps;
/**
* Create a new event instance.
*
* @param \App\Models\MyModel
*
* @return void
*/
public function __construct(MyModel $myModel)
{
$this->myModel = $myModel;
$this->originalAccessLevelProps = $this->myModel->getOriginal('level');
}
}
Слушатели/Модели/MyModel/MyModelSavedEventListener.php
<?php
namespace App\Listeners\Models\MyModel;
use Log;
use App\Models\MyModel;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Events\Models\MyModel\MyModelSavedEvent;
class MyModelSavedEventListener implements ShouldQueue
{
/**
* The queue connection that should handle the job.
*
* @var string
*/
public $connection = 'sqs';
/**
* The number of times the job may be attempted.
*
* @var int
*/
public $tries = 3;
/**
* The number of seconds the job can run before timing out.
*
* @var int
*/
public $timeout = 60;
public function __construct()
{
// ..
}
/**
* This job should only be queued if the level of myModel
* has been updated.
*
* @param \App\Events\Models\MyModel\MyModelSavedEvent $event
*
* @return bool
*/
public function shouldQueue(MyModelSavedEvent $event)
{
$prevLevel = $event->myModel->getOriginal('level');
$currLevel = $event->myModel->level;
return $prevLevel !== $currLevel;
}
public function handle(MyModelSavedEvent $event): void
{
$prevLevel = $event->myModel->getOriginal('level');
$currLevel = $event->myModel->level;
Log::info([
'Running handle!',
$event->myModel->getOriginal(), // This returns an empty array
$event->originalAccessLevelProps, // This is null
$event->myModel->id, // This returns a string
$prevLevel, // This returns null
$currLevel // This contains the latest value
]);
// ..
}
}
tests/app/Listeners/Models/MyModel/MyModelSavedEventListener.php
<?php
public function testSample()
{
Queue::fake();
$myModel = MyModel::where(...)->first();
Queue::assertNothingPushed();
// This will trigger the event
$myModel->level = 'new level';
$myModel->save();
Queue::assertPushedOn('sqs', MyModelSavedEventListener::class);
}
Я ожидал, что аналогично тому, как это работает вне теста, я смогу сравнить старые и новые значения.
Изменить. Событие запускается через свойство $dispatchesEvents
MyModel:
/**
* The event map for the model.
*
* @var array
*/
protected $dispatchesEvents = [
'saved' => \App\Events\Models\MyModel\MyModelSavedEvent::class,
];
Обновление: выяснилось, что моя модель действительно не сериализуется. Просто getOriginal()
по-прежнему возвращает пустой массив при вызове в методе слушателя handle()
MyModelSavedEventListener
- person Salim Djerbouh   schedule 26.08.2019