队列中的模型没有查询结果


Laravel 5.1 No query results for model in queue

我正在尝试从其官方文档中学习laravel数据库队列。我已经完成了文档中给出的配置。

这是我的工作:

<?php
namespace App'Jobs;
use App'SearchLog;
use App'Jobs'Job;
use Illuminate'Queue'SerializesModels;
use Illuminate'Queue'InteractsWithQueue;
use Illuminate'Contracts'Bus'SelfHandling;
use Illuminate'Contracts'Queue'ShouldQueue;
class SendTicket extends Job implements SelfHandling, ShouldQueue
{
    use InteractsWithQueue, SerializesModels;
    protected $log;
    protected $searchLog = array();

    public function __construct(SearchLog $log , $data = array())
    {
        $this->log = $log;
        $this->searchLog = $data;
    }
     /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
      $this->log->create($this->searchLog);     
    }

在我的控制器中我这样调用

public function store(Request $request)
{
 $searchLog = array();
 // searchLog contains the data to be inserted into database 
 $log = new SearchLog();
 $this->dispatch(new SendTicket($log , $searchLog));
 }

当我运行php artisan queue:listen时,我得到的错误如下

[Illuminate'Database'Eloquent'ModelNotFoundException]没有查询[App'SearchLog].

但是当我像这样编辑作业时

//only edited code 
public function __construct($data = array())
{
    $this->searchLog = $data;
}
/**
 * Execute the job.
 *
 * @return void
 */
public function handle()
{
  SearchLog::create($this->searchLog);   
}

当这样调用

 public function store(Request $request)
 {
    $searchLog = array();
    // searchLog contains the data to be inserted into database 
    $this->dispatch(new SendTicket($searchLog));
 }

它工作正常,数据被插入。
这里,我的问题是:

  1. 如何将对象发送到队列
  2. 发送数据到队列以便我们可以处理的最佳方式是什么?

问题在于use Illuminate'Queue'SerializesModels;,它试图序列化您传递给构造函数的SearchLog $log参数。由于您的模型尚未保存,因此它没有标识符。

根据Laravel文档:

如果您的排队作业在其构造函数中接受Eloquent模型,则只有模型的标识符将被序列化到队列中。当作业实际处理后,排队系统会自动处理从数据库中重新检索完整的模型实例。

解决方法是从您愿意保存模型的Job类中删除SerializesModels特征。

我也遇到了同样的问题。

如果你想把一个模型推到队列中,似乎只有它的ID会保存在有效负载中。所以,如果你还没有保存模型,它在处理程序中是不可用的。

毕竟我在队列和雄辩模型部分的文档中找到了它。

为了解决这个问题,我看到了两个解决方案,第一个是确保您有一个持久的模型:
public function store(Request $request)
{
 $searchLog = array();
 // searchLog contains the data to be inserted into database 
 $log = new SearchLog();
 //Save the Searchlog beforehand if it doesn't have any data constraints
 $log->save();
 //Dispatch the Job with the saved Model
 $this->dispatch(new SendTicket($log , $searchLog));
 }

将完整的模型保存过程仅放在处理程序中,就像您在示例中所做的那样。

//Full saving/initializing is happening here
public function handle()
{
  SearchLog::create($this->searchLog);   
}

在我的情况下,我必须在高性能进程中将模型保存到数据库中,所以我将其完全放在处理程序中,我的进程不依赖于db保存速度。所以我会把它放在handle()函数中

如果模型尚未保存或持久化,通常会引发此问题。检查您的模型实例和持久性。另一个可能引起这个问题的是多租户。因此,如果您正在使用或构建带有多个数据库的多租户应用程序,您可能需要找到一种方法将数据库连接传递到队列,或者只是使用taylor Otwell在这里[5.4]中所述的数据数组。