0

我正在尝试将 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"));
Inside 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 的模型不再存在,这是真的。

我的问题是如何触发事件来告诉具有特定 ID 的汽车已被删除。我不想创建另一个将扩展 Event 并且仅用于删除的类,我想使用我现有的 CarEvent 类。

我需要传递带有 Id 属性的简单对象,如下所示: 在此处输入图像描述

如果模型序列化时来自数据库的数据,我可以创建 Car 对象并设置它Id的属性并以某种方式禁用休息吗?

4

1 回答 1

1

序列化时不会出现问题,而是反序列化时会出现问题。你看,你的 Event 使用了SerializesModelstrait。此 trait 有以下方法:

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);
}

这个 trait 将模型序列化为 a ModelIdentifier,它只包含类名和 id。反序列化时,使用该信息从数据库中重新获取模型。在您的删除情况下,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];
    }
}
于 2016-10-12T21:00:56.507 回答