具有表名的雄辩模型在排队后动态设置中断(Laravel 5.8)

时间:2019-07-04 23:48:53

标签: laravel eloquent laravel-5.8 laravel-queue

我已经在模型上动态设置表名,但是由于模型序列化,它在排队时会中断。

我需要该值才能持久。

我需要能够将作业设置为队列,给定一个表名,获取其中的所有行,一个接一个地处理它们,直到没有更多的行了。 但是,此表可能会更改其名称,但不会更改其结构,因此我正在使用模型来读取/更新每一行。

但是,我发现在将作业发送到队列之后,模型的table属性恢复为在模型类中设置的原始属性。

DataSource.php

class DataSource extends Model
{
    protected $table = '';
}

MyJob.php

public function processTable(string $table)
{
    $datasource = new DataSource();
    $datasource->setTable($table);
    logger('COUNT: '.$datasource->count());

    $datasource::chunk(3, function(...){
        ...
    });
}

用户输入: my_table

之前测试::dispatch

dump($datasource->getTable())欢呼my_table

dump('COUNT: '.$datasource->count());保护正确的行数

运行队列作业时:

local.ERROR: SQLSTATE[42000]: Syntax error or access violation: 1103 Incorrect table name '' (SQL: select * from `` order by ``.`id` asc limit 3 offset 0)... 

如您所见,模型的$table属性在分派到数据库后的任何时间都会在模型的反序列化中丢失。

我不确定我的假设。如果这确实在发生,我需要有人确认或纠正我。

需要是:保留从队列中拉出时作业要处理的正确表名。

1 个答案:

答案 0 :(得分:0)

是否在分派之前将table属性存储在作业中?对于使用队列时要传递的任何数据,这是必需的。以下示例对我有用。

/App/Jobs/DataSourceJob.php

<?php

namespace App\Jobs;

use App\DataSource;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

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

    // this is where the table name will be stored
    protected $table;

    public function __construct($table)
    {
        // store the table name prior to entering queue
        $this->table = $table;
    }

    public function handle()
    {
        // retrieve the table name when the job runs
        $table = $this->table;

        $datasource = new DataSource();
        $datasource->setTable($table);
        logger('COUNT: '.$datasource->count());

        $datasource::chunk(3, function() {
            //
        });
    }
}

测试一下。

$table = '...';

dispatch(new DataSourceJob($table));