Mysql 表与laravel中的透视表连接
我正在使用laravel 5.8,我有四个表: 客户:id |名称|代码 任务:id |名称 客户任务:id |客户id |任务id 月份:id |客户id |任务id |执行日期 其中,Mysql 表与laravel中的透视表连接,mysql,laravel,Mysql,Laravel,我正在使用laravel 5.8,我有四个表: 客户:id |名称|代码 任务:id |名称 客户任务:id |客户id |任务id 月份:id |客户id |任务id |执行日期 其中,客户机和任务是多对多关系,客户机任务是数据透视表 我的想法是,我想像这样用html创建一个表 ------------------------------------------- |#|client name|task 1|task 2|task 3|task 4| ---------------------
客户机
和任务
是多对多关系,客户机任务
是数据透视表
我的想法是,我想像这样用html创建一个表
-------------------------------------------
|#|client name|task 1|task 2|task 3|task 4|
-------------------------------------------
|1| client 1 | ☐ | ☐ | /// | /// |
-------------------------------------------
|2| client 2 | /// | ☐ | ☐ | ☑ |
-------------------------------------------
|3| client 3 | ☐ | ☑ | ☑ | /// |
-------------------------------------------
每个月我都会获取所有客户机和所有任务,如果客户机有任务,我会显示一个复选框,否则我会显示一个空的td
,如果我完成了特定客户机的任务,我会检查此任务,并将client\u id
、task\u id
和当前日期exec\u date
插入monthly
表中
我纠正这个问题:
$clients = DB::table('monthlies as m')
->rightJoin('client_task as clta', function ($join){
$join->on('clta.client_id', '=', 'm.client_id')
->on('clta.task_id', '=', 'm.task_id')
->rightJoin('clients as cl', function ($join){
$join->on('clta.client_id', '=', 'cl.id')->where('cl.category',1);
})
->Join('category_task as cata', function ($join){
$join->on('clta.task_id', '=', 'cata.task_id')
->Join('categories as ca2', 'cata.category_id', '=', 'ca2.id')->where('ca2.type', 1)
->rightJoin('tasks as ta', 'cata.task_id', '=', 'ta.id')->where('ta.period', 1);
});
})
->select('m.*', 'cl.id as client_id', 'cl.name as client_name', 'cl.code as client_code', 'cl.legal_form as client_legal_form', 'ta.id as task_id', 'ta.name as task_name', 'ta.type as task_type', 'ta.period as task_period')
->get();
使用这段代码,我只能在client_任务表中获得客户机/任务
问题是,我想显示所有客户机或任务,即使客户机没有附加任何任务,反之亦然(不在
client\u task
pivot表中)。好的,这可能需要您对关系进行一些更改,但我想您会看到好处
透视表属性和模型 如果
客户机任务
和月任务
表之间的唯一区别是执行日期
,为什么不将这两个表合并到客户机任务
您可以向关系中添加透视表属性,如下所示:
Client.php
public function tasks()
{
return $this->belongsToMany(Task::class, 'client_task',`client_id`,'task_id')->withPivot(['exec_date']);
}
现在,当您获得客户机任务时,您可以使用透视属性($Task->pivot->exec\u date
)获取执行日期
您甚至可以制作专用的Pivot
模型,如文档所示
关系存在
您可以使用whereHas()
函数确定客户端是否具有给定的任务
Client::whereHas('tasks', function (Builder $query) use ($task) {
$query->where('id', $task->id);
})->get();
可以找到文档
模板
控制表格的大部分代码将使用简单的模板逻辑在blade视图中完成:
@foreach ($clients as $client)
<tr>
@foreach ($tasks as $task)
<td>
@if ($client->tasks->contains($task))
@if ($client->tasks->where('id', $task->id)->first()->pivot->exec_date)
... checked checkbox ...
@else
... unchecked checkbox ...
@endif
@else
...
@endif
</td>
@endforeach
</tr>
@endforeach
@foreach($clients作为$client)
@foreach($tasks作为$task)
@如果($client->tasks->contains($task))
@如果($client->tasks->where('id',$task->id)->first()->pivot->exec_date)
... 选中复选框。。。
@否则
... 未选中复选框。。。
@恩迪夫
@否则
...
@恩迪夫
@endforeach
@endforeach
我很好奇,为什么要用查询生成器编写“原始”SQL查询?如果您的关系设置正确,您只需执行Client::with('tasks')->get()
,然后循环遍历生成的Eloquent\Collection
。拉威尔会帮你完成所有这些繁重的工作;)我有许多客户机和许多任务,我希望获得所有客户机+所有任务+检查二进制文件(客户机任务)是否存在,如果不存在,我将在“datatable”中显示一个空的“td”,如果存在,我将检查该二进制文件是否存在于每月的表中,如果它存在,那么它将显示为“checked+disabled”复选框,如果不是,这意味着我没有完成这个客户端的任务,我将显示一个简单的复选框,因此我想在一个查询中获得所有这些,我仍然强烈建议使用elount
来完成这项任务,我将尝试发布一个答案,其中包括这一点,但它可能需要我一分钟!好的,非常感谢!!非常感谢您的详细回答,即使我发现我自己有两个问题,但没问题,它成功了。没问题,很高兴我能帮上忙!另一方面,不要认为您绝对需要在一个查询中完成所有操作。有时,单个大型查询实际上比几个较小的查询需要更长的时间,但这需要根据具体情况进行研究;)