Я пытаюсь использовать Pusher с Lumen для передачи событий клиентам для обновления данных.
Я создал очень простое событие:
class CarEvent extends Event implements ShouldBroadcast{
use SerializesModels;
public $car;
private $type;
public function __construct( Car $car, $type )
{
$this->car = $car;
$this->type = $type;
}
public function broadcastOn()
{
return ['car'];
}
public function broadcastAs()
{
return $this->type;
}
}
И я успешно запускаю его в моем контроллере, используя Event::fire(new CarEvent($car,"add"));
Внутри консоли Pusher я получаю событие ниже:
Моя проблема начинается, когда я пытаюсь отправить событие, когда запись удалена, ниже мой код:
public function deleteCar($id){
$car = $this->cars->findOrFail($id);
$car->delete();
$oldCar = new Car;
$oldCar->id=$id;
Event::fire(new CarEvent($oldCar,"delete"));
return Response::deleted();
}
Это всегда дает ModelNotFoundException
потому что модель с данным Id больше не существует, что является правдой.
Мой вопрос, как я могу запустить событие, которое скажет, что автомобиль с определенным идентификатором удален. Я не хочу создавать другой класс, который будет расширять Event и будет использоваться только для удаления, я бы хотел использовать свой существующий класс CarEvent.
Мне нужно передать простой объект с просто Id свойством, например, так:
Могу ли я создать объект Car и установить его Id
свойство и как-то отключить получение отдыха, если данные из базы данных, когда модель сериализуется?
Проблема возникает не при сериализации, а при десериализации.
Видите ли, ваше событие использует SerializesModels
черта характера. Эта черта имеет следующий метод:
protected function getRestoredPropertyValue($value)
{
if (! $value instanceof ModelIdentifier) {
return $value;
}
return is_array($value->id)
? $this->restoreCollection($value)
: (new $value->class)->newQuery()->useWritePdo()->findOrFail($value->id);
}
Эта черта сериализует модели как ModelIdentifier
, который просто содержит имя класса и идентификатор. При десериализации модель извлекается только из базы данных, используя эту информацию. В вашем случае удаления, findOrFail
делает это, ну, неудача.
Я думаю, вы можете придумать решение, которое соответствует вашим потребностям сейчас. Этот, например, я думаю, должен работать для разных моделей; если вы знаете, что хотите именно это для моделей автомобилей, вы можете сделать более простую.
protected function getRestoredPropertyValue($value)
{
if ($this->type == 'delete' && $value instanceof ModelIdentifier) {
$model = (new $value->class);
$pk = $model->getQueueableId();
$model->$pk = $value->id;
return $model;
}return parent::getRestoredPropertyValue($value);
}
Обновить
Вероятно, чище иметь отдельные События, как вы предлагаете. Все конструкторы должны получить модель Car, а для случая удаления вы создаете простой объект с нужными вам атрибутами.
abstract class CarEvent extends Event implements ShouldBroadcast
{
use SerializesModels;
public $car;
protected $type;
public function __construct(Car $car)
{
$this->car = $car;
}
public function broadcastOn()
{
return ['car'];
}
public function broadcastAs()
{
return $this->type;
}
}
class AddCarEvent extends CarEvent
{
protected $type = 'add';
}
class DeleteCarEvent extends CarEvent
{
protected $type = 'delete';
public function __construct(Car $car)
{
$this->car = (object) ['id' => $car->id];
}
}
Других решений пока нет …