我有以下相关表格:
tableA
- id
- value
tableB
- id
- tableA_id
- value
tableC
- id
- tableB_id
- value
tableD
- id
- tableC_id
- value
我通常使用嵌套的预先加载来从tableD获取tableaA的对象,例如:
$table_d = TableD::with('TableC.TableB.TableA')->find($id);
我得到一个这样的对象:
{
"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"
}
}
}
}
我想要实现的只是获取表D的对象,其对象来自表A,而最终对象中没有表C和表B,如下所示:
{
"id": 1,
"value": "value",
"tablea": {
"id": 1,
"value": "value"
}
}
}
我尝试在表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');
}
但它不起作用,因为当我执行以下查询时,它返回一些好的对象,其他的返回tableA = null:
$tables_d = TableD::with('TableA')->get()
我做错了什么或者有其他方法可以达到我的目的吗?
答案 0 :(得分:2)
你可以跳过一张桌子
this->hasManyThrough()
但是根据您真正想要的未来功能,您可能希望根据需要与您想要的任何代码建立多种关系。 QueryScopes以及。
答案 1 :(得分:1)
当它只是两个表和一个链接表之间时,通常可以使用一个有很多通过关系来映射表。除此之外,你还有另一个联盟,所以它不会比现在的好得多。
您是否考虑过直接从D到A的另一个映射表或一些非规范化?如果您总是需要加载它,那么您可能会因为有一些重复的fks来节省连接而受益。
这实际上取决于你的需求,它不是3NF(第三范式),也许它甚至不是2NF,但这就是为什么非规范化就像逗号一样使用...一般遵循规则但出于特定原因打破它们;在这种情况下,通过复制表中的FK引用来减少所需的连接数。
https://laravel.com/docs/5.6/eloquent-relationships#has-many-through
答案 2 :(得分:0)
您可以尝试这样做: - 在TableD Model中添加一个方法:
public function table_a()
{
return $this->TableC->TableB->TableA();
}
然后使用:TableD::with(table_a);