Laravel 5.5-事件上的序列化模型会导致模型识别剂错误



我有一个laravel事件,有一些听众。一些听众或他们的通知(取决于他们是否耗时(正在实现ShouldQueue,因此他们在redis队列的背景下运行。该事件默认情况下使用SerializesModels,但是当事件传递的模型之一是登录的用户,我们将其触发,这样:

$user = $this->user(); // logged in user instance
event(new UserCreatedPost($user, $post, $modelX, $modelY));

我无法访问各自侦听器中的用户关注者,以检查是否存在通知它们:

// In listener handle method
public function handle(UserCreatedPost $event){
    $followers = $event->user->followers()->get();
}

我得到此错误:

Call to undefined method IlluminateContractsDatabaseModelIdentifier::followers()

我能够使它上班的唯一方法是在下面添加事件唤醒:

public function handle(UserCreatedPost $event){
    // This fixes it, as it unserializes all the models
    // (even though we only need this model to be unserialized, not all of them)
    $event->__wakeup();

    $followers = $event->user->followers()->first();
    // If at least one follower exists send queued notification
    // else exit
}

i do 在同一事件和其他事件侦听器下其他一些听众中使用$user实例。我什至不知道$user是否应该首先序列化,但这是一个模型,因此父事件SerializesModels特质会自动序列化所有模型(我不知道有任何方法可以使此特定的特定方式模型不被序列化,而其他模型是(。

有没有更好的方法可以在听众中访问$user而无需进行wakeup调用?我与听众有很多活动,现在只能实现队列,所以我真的不想将wakeup添加到所有文件中会出现的所有文件中,但是我确实想排队一些听众或他们的。通知。一种替代方案是删除事件SerializesModels特征,甚至不必担心我尚未发现此错误下显示的错误。是否会出现任何问题,例如例如,通过实施替代方法,绩效还是其他方法?有更好的方法吗?

__wakeup()(在SerializesModels中定义(实际上应通过框架解开事件以执行其排队的侦听器时将被调用。该性状的全部目的是,它仅将模型标识符存储在序列化的字符串(而不是其他属性(中,并在不进行重新序列化时从数据库中重新加载模型。这样做是为了节省队列中的空间,还因为队列处理被延迟并且属性可能会改变。因此,您永远都不想序列化整个模型,其所有属性用于队列处理。

这也意味着,如果需要,您可以手动执行同样的事情。您只需将某些标识符传递给事件,而不是将模型对象传递给事件,然后将自己加载模型(不超过Model::find($id),对吗?(。

$user = $this->user(); // logged in user instance
event(new UserCreatedPost($user->id, $post->id, $modelX->id, $modelY->id));

和听众:

// In listener handle method
public function handle(UserCreatedPost $event){
    $user = User::find($event->user);
    $followers = $user->followers()->get();
    // the other stuff you want to do...
}

我必须承认,我还不熟悉排队的事件听众,只有排队的工作和类似的工作。但是根据您的描述,我想说的框架中可能有一个错误。实际排队不是侦听器,而是一个称侦听器的作业,称为CallQueuedListener

如果您将Laravel使用的行为用于排队的听众,则也可以自己使用相同的方法:不要排队活动侦听器,但让听众创建一个发送通知的排队作业。也许这更好。

最新更新