我几天来一直无法弄清为什么发生在下面我将要描述的以下行为。
以下代码的基本思想是更新任务,然后
EmployeeTaskAttached
事件EmployeeTaskDetached
那些已被删除任务的员工TaskEmployeesChanged
用于那些未受影响但需要使用新添加/删除的员工更新其任务员工列表的员工Task
模型应在加载关系的情况下进行广播在这里,我更新了一些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();
}
这是事件之一,但其他事件发生相同的行为。
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;
}
}
成功地广播并接收了事件本身,我没有得到的一件事是为什么已经在控制器中加载的Task
模型关系在事件中再次加载,因此,复制了数据库查询。
当我打开Laravel望远镜工具时,可以看到在控制器中执行了必要的查询,但是将Task
模型传递给事件后,事件作业将运行一些查询,这些查询已在控制器,再次。最后,如果我从任务中删除并添加了一些员工,尽管可能需要大约17个查询,但已经运行了约40个查询。
如果在行Task
之前的构造函数中记录传递给事件的$this->task = $task;
模型,则可以看到关系已经加载,但是当执行$this->task = $task;
时,laravel重新加载关系。
关系是否应该已经加载?如果没有,如何减少查询量?
可能这是Laravel望远镜故障,实际上没有执行这些查询吗?
答案 0 :(得分:0)
Laravel在将Task
模型实例推送到队列时对其进行序列化。广播发生时,Task
再次从数据库中检索。