Laravel Eloquent 表之间通过其他表的关系
Posted
技术标签:
【中文标题】Laravel Eloquent 表之间通过其他表的关系【英文标题】:Laravel Eloquent Relationship of tables through other tables in between 【发布时间】:2021-03-26 14:12:40 【问题描述】:在 Laravel 中,我在 LevelOne、LevelTwo、LevelThree 和 LevelFour 的 4 个模型之间有以下关系:
//LevelOne Model
public function levelTwo()
return $this->hasMany(LevelTwo::class);
//LevelTwo Model
public function levelOne()
return $this->belongsTo(LevelOne::class);
public function levelThree()
return $this->hasMany(LevelThree::class);
//LevelThree Model
public function levelTwo()
return $this->belongsTo(LevelTwo::class);
public function levelFour()
return $this->hasOne(LevelFour::class);
//LevelFour Model
public function levelThree()
return $this->belongsto(LevelThree::class);
我的目标是使用一个控制器,对于这个例子,文件称之为 JoinController ,并返回一个这样的字符串
[
"id": 1,
"name": "Entry 1 at level one",
"levelTwo": [
"id": 1,
"levelone_id": 1,
"name": "Entry 1 on level two",
"levelThree": [
"id": 1,
"leveltwo_id": 1,
"name": "Entry x on level three",
"levelFour": [
"id": 1,
"levelthree_id": 1,
"name": "Entry x on level four"
,
"id": 2,
"levelthree_id": 1,
"name": "Entry x on level four"
]
,
"id": 2,
"leveltwo_id": 1,
"name": "Entry x on level three",
"levelFour": [
"id": 3,
"levelthree_id": 2,
"name": "Entry x on level four"
,
"id": 4,
"levelthree_id": 2,
"name": "Entry x on level four"
]
]
,
"id": 2,
"levelone_id": 1,
"name": "Entry 2 on level two",
"levelThree": [
"id": 3,
"leveltwo_id": 2,
"name": "Entry x on level three",
"levelFour": [
"id": 5,
"levelthree_id": 3,
"name": "Entry x on level four"
,
"id": 6,
"levelthree_id": 3,
"name": "Entry x on level four"
]
,
"id": 4,
"leveltwo_id": 2,
"name": "Entry x on level three",
"levelFour": [
"id": 7,
"levelthree_id": 4,
"name": "Entry x on level four"
,
"id": 8,
"levelthree_id": 4,
"name": "Entry x on level four"
]
]
]
,
//.... same as previous, n times
]
到目前为止,我能够从 JoinController 成功返回“下一级”的信息:
public function getAllLevels()
return LevelOne::with('levelTwo')->get();
但是,当我尝试向下一层时,它会失败,如下所示:
public function getAllLevels()
return LevelOne::with('levelTwo')->with('levelThree')->get();
错误是:调用模型 [App\Models\LevelOne] 上的未定义关系 [levelThree]。
但是,如果我返回以下内容:
return LevelTwo::with('levelOne')->with('levelThree')->get();
这适用于一种关系“向上”和一种关系“向下”,但如果我添加 LevelFour 它将不起作用。 (是的,我在控制器顶部正确导入模型:使用 \App\Models\LevelOne; 使用 \App\Models\LevelTwo; ...等)
在普通的 SQL 中,我只需要编写一个查询来连接外键以获得所需的结果。在 Eloquent 中,当 LevelOne 模型不通过任何 ID 而是通过中间的其他模型表连接时,我不确定如何使 LevelOne 模型与 LevelFour 建立关系,例如级联连接。请指出正确的方向。
注意:像我之前展示的那样返回一个字符串(json)对我来说非常重要,我需要返回LevelOne的所有值,显示它在LevelTwo的关系中的所有行等等等等“ n" 次(在我的例子中是 4 次)。
【问题讨论】:
【参考方案1】:您可能需要更改 LevelThree 中的关系
//LevelThree Model
public function levelTwo()
return $this->belongsTo(LevelTwo::class);
public function levelFour()
return $this->hasOne(LevelFour::class);
然后你可以形成一个查询
public function getAllLevels()
return LevelOne::with('levelTwo.levelThree.levelFour')->get();
【讨论】:
我的原始代码与您建议更改LevelThree的关系正确,我在这里写错了。我已经用正确的代码编辑了这个问题。使用 with('levelTwo.levelThree.levelFour') 的查询非常简单,但我无法在文档中找到它。非常感谢!【参考方案2】:有几件事你可以看看。 首先,对于不是 2 而是 3 层之间的关系,尝试寻找 hasManyThrough。这样你就可以直接从 levelOne 到 levelThree,根本不需要调用 levelTwo。同样的方法,但是你可能需要尝试
如你所说 错误是:调用模型 [App\Models\LevelOne] 上的未定义关系 [levelThree]。
这是因为在调用 with() 时,您仍然对 LevelOne 执行此操作,而不是 LevelTwo。 LevelOne::with('levelTwo') 不会返回 LevelTwo,而是返回一个 LevelOne,它具有该名称下的 LevelTwo 的实例/实例,因此您可以访问它 $levelOne->levelTwo。如果你想调用'withs'来遍历返回的实例,你需要写一个逗号和下一个关系的名称,就像这样。
LevelOne::with('levelTwo.levelThree.levelFour')->get();
【讨论】:
以上是关于Laravel Eloquent 表之间通过其他表的关系的主要内容,如果未能解决你的问题,请参考以下文章
Laravel Eloquent 在与其他表连接后从关系中选择字段
一个模型和多个模型之间的 Laravel Eloquent 关系作为 MorphOne?
如何通过 laravel eloquent 模型 Laravel 5 加入三个表