首页 > 解决方案 > 由于 Illuminate\Queue\SerializesAndRestoresModelIdentifiers,Job 类内部的加载关系发生了变化

问题描述

我有一个接受User. hasMany我使用闭包在构造函数内的该模型中加载关系。不知何故,结果发生了变化,就好像闭包在到达方法时被丢弃了一样handle

像这样的东西:

class SomeJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected User $user;

    public function __construct(User $user)
    {
        // load children relationship where field = 3
        $this->user = tap($user)->load([
            'children' => function ($children) {
                $children->where('field', 3);
            }
        ]);

        dump($this->user->children->toArray());
    }

    public function handle()
    {
        dump($this->user->children->toArray());
    }
}

使用同步队列驱动程序,我创建了一个路由来调度该作业并在浏览器中检查结果。转储的结果是不同的。

根据 laravel 调试栏,关系查询在内部重复\vendor\laravel\framework\src\Illuminate\Queue\SerializesAndRestoresModelIdentifiers.php:102但没有闭包。

询问 地点
select * from "users" where "users"."id" = 6 and "users"."deleted_at" is null limit 1 \vendor\laravel\framework\src\Illuminate\Support\Traits\ForwardsCalls.php:23
select * from "children" where "children"."usuario_id" in (6) and "field" = 3 and "children"."deleted_at" is null \app\Jobs\SomeJob.php:30
select * from "users" where "users"."id" = 6 limit 1 \vendor\laravel\framework\src\Illuminate\Queue\SerializesAndRestoresModelIdentifiers.php:102
select * from "children" where "children"."usuario_id" in (6) and "children"."deleted_at" is null \vendor\laravel\framework\src\Illuminate\Queue\SerializesAndRestoresModelIdentifiers.php:102

这是正常行为吗?

标签: phplaraveleloquent

解决方案


当模型以这种方式序列化时,只使用一个“标识符”。它实际上并没有序列化模型serialize。这就是为什么它必须在反序列化时查询模型,因为只有一个标识符才能再次找到模型。

它知道在反序列化后加载关系,因为该信息与模型的标识符一起保存,但它只是加载了什么关系,而不是它是如何加载的或当前在其中的什么。因此,它将加载先前通过简单调用加载的关系,并load在反序列化时使用关系名称。

打开该特征SerializesAndRestoresModelIdentifiers,您将看到它是如何做到的。


推荐阅读