【问题标题】:Put function in Queue but not loaded relation data | Laravel Queue将函数放入队列但未加载关系数据 | Laravel 队列
【发布时间】:2018-06-15 13:12:34
【问题描述】:

我需要生成用户的 pdf 及其相关数据。我在控制器中创建了一个函数来生成 pdf(使用 snappy-pdf 包)。数据加载正确,生成pdf并成功上传到S3。现在我正在尝试将该函数与用户数据一起放入队列中。但是没有为生成pdf加载数据。相反,它只加载用户模型数据,而不加载相关数据(如属性和联系人)。

$user = User::where("id", 83)->with(['property', 'contacts'])->first();
$contact_list = [];
if(count($user->contacts)){
    foreach ($user->contacts as $contact) {
        array_push($contact_list, $contact->contactDetails->name);
    }
} 
$user->contact_list = $contact_list;
return view('pdf_view', ["user" => $user]);
if($request->has('download')) {

    // dispatch the event
    /*$pdf = PDF::loadView('pdf_view', ["user" => $user]);
            // upload pdf
        Storage::disk('s3')->put("user-invoice/user.pdf", $pdf->output(), 'public');*/
    dispatch(new GenerateSignedDocument($user));
    return "done";         
}

这是我的工作文件。

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Log;
use PDF;
use Storage;

class GenerateSignedDocument implements ShouldQueue
{
    use InteractsWithQueue, Queueable, SerializesModels;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    private $user;
    public function __construct($user)
    {
        $this->user = $user;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
         // Log::info('Showing user: '.$this->user);
        $pdf = PDF::loadView('pdf_view', ["user" => $this->user]);
            // upload pdf
        Storage::disk('s3')->put("user-invoice/user.pdf", $pdf->output(), 'public');
    }
}

【问题讨论】:

  • Laravel 版本是什么?
  • 现在是 5.4 和另一件事,这个队列功能正在工作,但没有加载实际数据。这意味着它会创建一个不完整的 pdf。
  • 你能把你的全动作控制器的参数和所有东西放在一个要点上吗,模型和工作对我来说更好看吗?但是,我认为您应该遵循事件驱动的方法。请参阅 Laravel 文档以检查它如何加载与事件相关的信息。 laravel.com/docs/5.4/events#defining-events
  • 我认为事件也派发了一个作业,所以数据可以这样加载?

标签: laravel queue lazy-loading


【解决方案1】:

SerializesModels trait 仅存储模型的键,并在模型未序列化时从数据库中重新加载模型,因此这可能不会加载您的关系。

这通常是一个很大的好处,因为当排队的作业实际运行时,您会收到新数据,而不是计划作业时的数据。

无论如何,最好的办法是:

  1. 在作业本身中加载作业所需的关系,而不是依赖于它们被预加载。

  1. 将属性和联系人作为单独的依赖项传递给您的作业类。

【讨论】:

  • 意思是我需要在job的handler函数中调用带有相关数据的模型?
  • 我不确定你在问什么。如果您选择上面的路线 1,您希望在 handle() 函数中加载相关数据,而不必担心在调度作业时加载它。
【解决方案2】:

我不知道这是否是完美的解决方案,但我这样做并且工作正常。 我调用了在处理函数中执行 pdf 生成所需的函数(uploadUserDocument)。

/**
 * Execute the job.
 *
 * @return void
 */
public function handle()
{
    app('App\Http\Controllers\UserController')->uploadUserDocument($this->user_id);
}

并在控制器中发送事件

dispatch(new GenerateSignedDocument(83));

并将生成pdf所需的代码放在uploadUserDocument函数中。

/**
     * Function is used to Save document to s3 cloud
     * @param $user_id
     * @return Response
     */
    public function uploadUserDocument($user_id){
        $pdf = PDF::loadView('pdf_view', ["user" => $user]);
            // upload pdf
        Storage::disk('s3')->put("user-invoice/user.pdf", $pdf->output(), 'public');
    }

【讨论】:

    猜你喜欢
    • 2014-02-22
    • 2020-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-08
    • 2018-03-15
    • 1970-01-01
    • 2019-05-16
    相关资源
    最近更新 更多