将新创建的 Eloquent 模型保存为作业属性会导致作业无法被处理

问题描述 投票:0回答:3

我有一个 Laravel 作业,它应该接受新创建的 Eloquent 模型作为构造函数属性,然后在 handle() 方法中对其执行 save() 操作。但是,一旦我尝试将模型保存到私有属性,handle() 方法就不再执行。这是代码:

MyController.php:

$category = new Category;
SaveModelJob::dispatch($category);

保存模型作业.php

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

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

    private $model;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($model)
    {
        //
        dump('saving as property'); // this gets executed
        $this->model = $model; // <--- PROBLEMATIC CODE
        dump('saved as property'); // this also gets executed
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        dump("handling"); // <--- This stops being executed as soon as the PROBLEMATIC CODE above is added
        // a $this->model->save() operations is intended here
        

    }
}

在我的真实控制器中,在将 $category 传递给 SaveModelJob 之前设置了一些模型属性,但为了简单起见,我删除了大部分不相关的代码。为了解决一些可能的问题:

  • 类别模型是一个简单的 Eloquent 模型
  • 我在 .env 中设置了 QUEUE_CONNECTION=sync ,如果有问题的代码不存在,handle()方法实际上会被执行,所以我不认为问题与队列直接相关
  • 如果我从数据库传递一个现有的 Category 对象,而不是新创建的(但未保存)对象,则会到达 handle() 方法。
  • 我正在使用 Laravel 8.34。

我怀疑 Job 对象的行为与常规类不同,并且在初始请求生命周期之外很晚才到达 handle() 方法,这可能会对稍后访问私有属性的方式产生影响(特别是当队列驱动程序不是“同步”,而是 Redis 时),但我在日志中没有收到此类错误。

你知道问题是什么吗?

php laravel eloquent model jobs
3个回答
3
投票

当您将对象分派到队列时,该对象将被保存到队列中,但如果您传递 Eloquent 模型,它将通过其 id(或主键)从数据库中引用,而不是完全保存到队列中有效负载

为了避免使用未保存的模型,只需将其作为数组发送即可。

控制器

$category = new Category;
SaveModelJob::dispatch($category->toArray()); //or build the array from scratch

保存模型作业

public function __construct($model)
{
    //
    dump('saving as property');
    $this->model = Category::make($model);
    dump('saved as property');
}

如果您对所有模型使用相同的脚本,请为该类添加另一个属性

控制器

$category = new Category;
SaveModelJob::dispatch($category->toArray(), Category::class); //or build the array from scratch

保存模型作业

public function __construct($model, $eloquentClass)
{
    //
    dump('saving as property');
    $this->model = $eloquentClass::make($model);
    dump('saved as property');
}

0
投票

我没有看到您已保存模型。请创建或保存您的模型,然后将其发送给工作:

$category->save();

还要确保将正确的模型传递给作业,最好注入模型:

    public function __construct(Category $category)
    {
        $this->model= $category;
    }

但是如果你不注入模型类它仍然有效。


0
投票

我发现了一个技巧,我们可以将对象作为对象数组传递,它将完全保存在有效负载中)

© www.soinside.com 2019 - 2024. All rights reserved.