Search code examples
phplaravelqueuelazy-loading

Put function in Queue but not loaded relation data | Laravel Queue


I need to generate a pdf of user with their related data. I have created a function in controller to generate pdf(using snappy-pdf package). Data is loaded properly, pdf generated and uploaded on S3 successfully. Now I am trying to put that function in queue with user data. But data is not loaded for generation pdf. Instead it only laod the user model data but not the related data (like property and contact).

$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";         
}

And here is my job file.

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');
    }
}

Solution

  • I don't know this is the perfect solution or not but I do this and work fine. I called the required function(uploadUserDocument) for performing pdf generation in the handler function.

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

    and dispatch the event as it is in the controller

    dispatch(new GenerateSignedDocument(83));
    

    and put the required code for generating pdf in the uploadUserDocument function like this.

    /**
         * 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');
        }