Rus*_*man 5 php laravel eloquent laravel-eloquent laravel-5.5
我有以下相关表格:
tableA
- id
- value
tableB
- id
- tableA_id
- value
tableC
- id
- tableB_id
- value
tableD
- id
- tableC_id
- value
Run Code Online (Sandbox Code Playgroud)
我通常使用嵌套的eager加载来从tableD获取tableaA的对象,例如:
$table_d = TableD::with('TableC.TableB.TableA')->find($id);
Run Code Online (Sandbox Code Playgroud)
我得到一个像这样的对象:
{
"id": 1,
"value": "value",
"tableC_id": 1,
"tablec": {
"id": 1,
"value": "value",
"tableB_id": 1,
"tableb": {
"id": 1,
"value": "value",
"tableA_id": 1,
"tablea": {
"id": 1,
"value": "value"
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想要实现的只是获取表D的对象,其对象来自表A,而最终对象中没有表C和表B,如下所示:
{
"id": 1,
"value": "value",
"tablea": {
"id": 1,
"value": "value"
}
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试在表D的模型文件中添加此函数:
public function TableA()
{
return $this->belongsTo('App\Models\TableC', 'tableC_id')
->join('tableB','tableC.tableB_id','=','tableB.id')
->join('tableA','tableB.tableA_id','=','tableA.id')
->select('tableA.id', 'tableA.value');
}
Run Code Online (Sandbox Code Playgroud)
但它不起作用,因为当我执行以下查询时,它返回一些好的对象,其他的返回tableA = null:
$tables_d = TableD::with('TableA')->get()
Run Code Online (Sandbox Code Playgroud)
我做错了什么还是有另一种方式来实现我想要的东西?
当只有两个表和一个链接表之间时,通常可以使用具有多个直通关系的映射表。除此之外,您还有另一个加入,因此它不会比您当前的加入好多少。
您是否考虑过直接从 D 到 A 的另一个映射表或一些非规范化?如果您总是需要像这样加载它,您可能会受益于在连接上保存一些重复的 fks。
这实际上取决于您的需求,它不是 3NF(第三范式),也许甚至不是 2NF,但这就是为什么非规范化就像逗号的使用......一般遵循规则,但由于特定原因而打破它们;在这种情况下,通过复制表中的 FK 引用来减少所需联接的数量。
https://laravel.com/docs/5.6/eloquent-relationships#has-many-through