我需要按关系过滤我的雄辩查询。我有以下关系:
User **has many** achievements
Game **has many** achievements
现在我需要将用户 A 的成就过滤到游戏 B 中获得的成就。这可以通过以下方式完成:
$user->achievements()->whereGameId($game->id)
这很好,但是我可以直接使用$game对象而不是按丑陋的ID列过滤吗?
在我看来,将
$game
对象注入闭包方法并在预先加载时进行查询是一种更好的方法。
whereHas
和 orWhereHas
用于通过查询关系来限制结果。
$game = Game::find($gameID);
//magic happens here
$users = User::whereHas('achievements', function($query) use($game){
$query->where('gameId', $game->id);
})
->with('achievments') //if you want to have them inside collection
->get();
这限制了User
(主集合结果(和achievments
(关系(。
下面是详细信息(查询关系(。
如果你只想过滤achievments
,而不是User
集合,你只需要一个预先加载的闭包函数:
$game = Game::find($gameID);
//magic happens here
$users = User::with(
array('achievements' => function($query) use($game){
$query->where('gameId', $game->id);
}))
->get();
这只会限制achievments
关系,但不影响User
(主集合(
这是详细说明(预先加载污渍(
编辑:
因此,这是允许您执行此操作的 PR https://github.com/laravel/framework/pull/4267:
// 'game' being relation on the Achievement model
$user->achievements()->hasIn('game', $game);
// or equivalent dynamic call
$user->achievements()->hasInGame($game);
// of course you may use it like any other Builder method, for example:
User::hasInAchievements($achievement)->get();
没有直接的方法可以做到这一点,除非Game
与User
有某种关系。
需要明确的是,假设User
和Game
相关,那么您可以在游戏集合上访问成就 集合注入Game
模型而不是"丑陋"$game->id
:
$user->games->find($game)->achievements;