Laravel再次广播事件的构造函数调用类型暗示模型关系

问题描述 投票:1回答:1

我现在几天都无法弄清楚为什么我在底部描述的下列行为发生了。 以下代码的基本思想是更新任务,和

  • 向分配给该任务的员工广播EmployeeTaskAttached事件
  • 为那些已被移除任务的员工广播EmployeeTaskDetached
  • TaskEmployeesChanged适用于那些未受影响但需要使用新添加/删除的员工更新其任务员工列表的员工
  • Task模型应该在关系加载的情况下进行广播

Task controller

在这里,我更新了一些Task字段,从sync()返回的数据和相应的广播事件中获取附加/分离员工的ID。请注意,我加载了视图所需的任务关系,其中显示了任务。 $task->load('project','status','parent_task','tags') ;

 public function update (Request $request, Task $task)
{    
  $task->name = $request->task['name'];
  $task->date_due = $request->task['date_due'];
  $task->type()->associate($request->task['task_type_id']);  
  $task->status()->associate($request->task['status_id']);
  $task->load('project','status','parent_task','tags') ;

  if($request->has('task.employees') )
  {
    $originalEmployees = $task->employees->pluck('id'); 
    $changedEmployees = $task->employees()->sync($request->input('task.employees',[]));
    $detachedEmployees = $changedEmployees['detached'];
    $attachedEmployees = $changedEmployees['attached'];
    //$employeesToUpdate contains the original task employee id's that have not been detached or attached
    $employeesToUpdate = $originalEmployees->diff(array_merge($detachedEmployees,$attachedEmployees ));
    if( $attachedEmployees || $detachedEmployees)
    { 
      //broadcasted only if there is a change in employees
      broadcast(new TaskEmployeesChanged($task,$employeesToUpdate));
    }
    if($attachedEmployees)
    { 
      broadcast(new EmployeeTaskAttached($task,collect($attachedEmployees)));
    }
    if($detachedEmployees)
    {
     broadcast(new EmployeeTaskDetached($task,collect($detachedEmployees)));
    } 

  }  
  $task->save();
}

Broadcast event

这是其中一个事件,但其他事件也会发生相同的行为。

namespace App\Events\Tasks;  
use Illuminate\Broadcasting\Channel;  
use Illuminate\Queue\SerializesModels;  
use Illuminate\Broadcasting\PrivateChannel;  
use Illuminate\Broadcasting\PresenceChannel;  
use Illuminate\Foundation\Events\Dispatchable;  
use Illuminate\Broadcasting\InteractsWithSockets;  
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;  
use App\Models\Task;  
use App\Interfaces\UserInterface;  
class EmployeeTaskAttached implements ShouldBroadcast  
{  
    use Dispatchable, InteractsWithSockets, SerializesModels;  

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public $task,$employee_id ;
    public function __construct(Task $task,$employee_id   )
    {
      $this->task = $task;
      $this->employee_id = $employee_id; 
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    { 
      $task_list_channels = $this->employee_id->map(function ($id){
        $channel = new PrivateChannel('task_list_'.$id);
       return $channel;
      }) 
      ->all();

      return $task_list_channels; 
    } 


}

Problem

事件本身被广播并成功接收,我不知道的一件事是为什么在事件中再次加载已经在控制器中加载的Task模型关系,因此,复制数据库查询。 当我打开Laravel Telescope工具时,我可以看到在控制器中执行了必要的查询,但是一旦将Task模型传递给事件,事件作业就会运行一些已经在控制器中执行的查询。最后,如果我从任务中删除并添加一些员工,则最多会运行约40个查询,即使它应该需要大约17个查询。 如果我记录Task模型,传递给事件,在此行$this->task = $task;之前的构造函数中,我可以看到关系已经加载,但是当执行$this->task = $task;时,laravel再次加载关系。 是否已经加载了关系?如果没有,我怎么能减少查询量?这可能是一个Laravel望远镜故障,那些查询实际上没有被执行?

php laravel
1个回答
0
投票

当laravel被推送到队列时,它会序列化Task模型实例。当广播发生时,再次从数据库中重新检索Task

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