Reputation: 2898
Can you see what I'm doing wrong with the following code?
/**
* Listen to the AdministerRole deleted event.
* @param AdministerRole $role
* @return void
*/
public function deleted(AdministerRole $role)
{
//This works
$arg_list = func_get_args();
event(new BroadcastingModelEvent($arg_list, 'deleted'));
//This throws an exception
//event(new BroadcastingModelEvent($role, 'deleted'));
//No query results for model [App\Models\AdministerRole].
}
When I delete an AdministerRole
model and pass the parameter $role
to my BroadcastingModelEvent, an exception is thrown suggesting that perhaps the model can't be found because it's already deleted:
No query results for model [App\Models\AdministerRole]].
However, if I use func_get_args
to get the parameters which were passed to the function, and pass the resulting array to BroadcastingModelEvent, I can see a JSON representation of the model collected by Pusher on the client side. What on earth is the difference that's causing this exception?
Upvotes: 1
Views: 1550
Reputation: 2898
I got the clue to this problem from this SerializesModels with recently deleted models discussion on the Laravel GitHub page.
My BroadcastingModelEvent
's constructor is expecting an Eloquent Model. If I use the SerializesModels trait, it throws an No query results for model
exception as discussed in the GitHub page if the event is deleted
. The argument seems to be that if the model is already deleted it shouldn't be serializable - or something. The logic escapes me because the deleted event receives the model which has just been deleted and that model is accessible within the deleted event handler, and furthermore, you can call toArray()
or toJson()
to serialise it! That's my solution. The observer deleted
method calls toArray()
on the model passed to it and sends that array to the BroadcastingModelEvent
constructor. I simply commented out SerializesModels
and pre-serialised my model in the observer. If you can explain and justify that seeming inconsistency I'll bake you some shortbread.
public function deleted(AdministerRole $role)
{
event(new BroadcastingModelEvent($role->toArray(), 'deleted'));
}
And BroadcastingModelEvent
handles it
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Database\Eloquent\Model as Model;
/**
* https://github.com/laravel/framework/issues/10733
*/
class BroadcastingModelEvent implements ShouldBroadcast {
use Dispatchable,
InteractsWithSockets;
//Throws an exception after the deleted event.
//SerializesModels;
public $modelArray;
public $eventType;
public function __construct($modelArray, $eventType) {
$this->modelArray = $modelArray;
$this->eventType = $eventType;
}
public function broadcastOn() {
return new Channel('MyObservers');
}
public function broadcastAs() {
return 'MyBroadcastEvent';
}
}
Upvotes: 1