** 更新帖子:我认为使用Eloquent实际上是不可能的,所以我采取了不同的方法,无论如何,谢谢! **
考虑以下简化表:
content
---------------
| id | name |
---------------
| 1 | news |
| 2 | review |
---------------
games
-------------
| id | name |
-------------
| 8 | halo |
| 9 | gta |
-------------
releases
-------------------------------
| id | name | game_id |
-------------------------------
| 14 | halo for ps3 | 8 |
| 15 | halo for wii | 8 |
| 16 | gta for ps4 | 9 |
-------------------------------
content_releases
-------------------------------------
| content_id | release_id | game_id |
-------------------------------------
| 1 | 14 | 8 |
| 1 | 15 | 8 |
| 2 | 15 | 8 |
| 2 | 16 | 9 |
-------------------------------------
content
项可以通过releases
表格链接到多个content_games
。releases
属于一个game
content
项与releases
相关联,它们本身也与games
相关联。我的模特看起来像这样:
class Content extends \Eloquent
{
public function games()
{
return $this->belongsToMany('Models\Game', 'content_game');
}
}
class Game extends \Eloquent
{
public function releases()
{
return $this->belongsToMany('Models\Release', 'content_game');
}
}
class Release extends \Eloquent
{
public function content()
{
return $this->belongsToMany('Models\Content', 'content_game');
}
}
我正在尝试编写一个相对快速的延迟加载的雄辩查询,它可以让我获得内容,相关游戏嵌套在其下,然后是相关版本。所以我希望输出数组看起来像这样:
Array
(
[0] => Array
(
[id] => 1
[name] => News
[games] => Array
(
[0] => Array
(
[id] => 8
[name] => Halo
[releases] => Array
(
[0] => Array
(
[id] => 14
[name] => Halo for PS3
)
[1] => Array
(
[id] => 15
[name] => Halo for Wii
)
)
)
)
)
[1] => Array
(
[id] => 2
[name] => Review
[games] => Array
(
[0] => Array
(
[id] => 8
[name] => Halo
[releases] => Array
(
[0] => Array
(
[id] => 15
[name] => Halo for Wii
)
)
)
[1] => Array
(
[id] => 9
[name] => GTA
[releases] => Array
(
[0] => Array
(
[id] => 16
[name] => GTA for PS4
)
)
)
)
)
)
Content::with('games', 'games.releases')->toArray();
无法充分利用3列表content_releases
将它们连接在一起,因为Eloquent只根据其中两列进行查询。因此我需要添加约束games.releases。
它有效(下面的代码),但效率并不高:
Content::with(['games' => function ($query) {
$query->groupBy(['game_id','game.id','pivot_content_id']);
},
'games.releases' => function ($query) {
$query->has('content');
}]);
它产生以下查询:
select * from "content" limit 10 offset 0
select "game".*, "content_game"."content_id" as "pivot_content_id", "content_game"."game_id" as "pivot_game_id"
from "game"
inner join "content_game" on "game"."id" = "content_game"."game_id"
where "content_game"."content_id" in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
group by "game_id", "game"."id", "pivot_content_id"
select "releases".*, "content_game"."game_id" as "pivot_game_id", "content_game"."release_id" as "pivot_release_id"
from "releases"
inner join "content_game" on "releases"."id" = "content_game"."release_id"
where "content_game"."game_id" in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
and (
select count(*)
from "content"
inner join "content_game" on "content"."id" = "content_game"."content_id"
where "content_game"."release_id" = "releases"."id"
) >= 1
有人能建议使用相同的输出更有效地解决这个问题吗?
感谢。
答案 0 :(得分:4)
是的,这个问题有点过时了,但我不久前就自己努力了,一个正确的答案可能对其他人有用:)
设置数据库表和关系的方式存在一些问题,所以让我们先将它们排除在外:
如果我理解正确,内容与游戏之间存在多对多的关系,游戏与发行版之间存在一对多的关系。因此,您将为内容和游戏之间的关系创建一个数据透视表,并在发布表上使用外键。这意味着重命名枢轴(为清楚起见)并删除release_id列。
完成后,我们必须更新模型关系。内容属于ToMany游戏,游戏属于多种内容和游戏有很多版本。
现在只需要使用nested eloquent relationships,从那时起可能已添加到文档中的内容......我们已经完成了。
Content::with(['games', 'games.releases'])->get()->toArray();
答案 1 :(得分:0)
试试这个..
Content::with('games')->with('releases')->with('content')->get()->toArray();