J'essaie actuellement de créer une requête imbriquée, comme suit:
public function getChallenge($user_id, $opponent_id)
{
$challenge = $this->challenges()
->where('open', true)
->where(function($query) use ($user_id, $opponent_id) {
$query->where('player_1', $user_id)
->where('player_2', $opponent_id);
})
->orWhere(function($query) use ($opponent_id, $user_id) {
$query->where('player_1', $opponent_id)
->where('player_2', $user_id);
})
->first();
return $challenge;
}
Cela crée la requête suivante par exemple:
select * from `site_challenges_leagues`
where `site_challenges_leagues`.`league_id` = '1'
and `open` = '1'
and (`player_1` = '3' and `player_2` = '1')
or (`player_1` = '1' and `player_2` = '3')
limit 1
Cependant, cela renvoie toujours la première valeur de la table (où open
est soit 1
ou 0
), ce qui est incorrect. Pour que la requête soit correcte, elle doit contenir les deux ensembles de requêtes AND
entre crochets, comme suit:
select * from `site_challenges_leagues`
where `site_challenges_leagues`.`league_id` = '1'
and `open` = TRUE
and ((`player_1` = '3' and `player_2` = '1')
or (`player_1` = '1' and `player_2` = '3'))
limit 1
Est-il possible de faire cela à Laravel? J'ai tenté de le faire; cependant, il a échoué:
public function getChallenge($user_id, $opponent_id)
{
$challenge = $this->challenges()
->where('open', true)
->where(function($q) use ($user_id, $opponent_id) {
$q->where(function($query) {
$query->where('player_1', $user_id)
->where('player_2', $opponent_id);
})
->orWhere(function($query) {
$query->where('player_1', $opponent_id)
->where('player_2', $user_id);
})
})
->first();
return $challenge;
}
Toute aide est grandement appréciée.
Vous étiez très proche de la réponse
$challenge = $this->challenges()
->where('open', true)
->where(function($q) use ($user_id, $opponent_id) {
$q->where(function($query) use ($opponent_id, $user_id){
$query->where('player_1', $user_id)
->where('player_2', $opponent_id);
})
->orWhere(function($query) use ($opponent_id, $user_id) {
$query->where('player_1', $opponent_id)
->where('player_2', $user_id);
});
})
->first();
Ici sont les différences entre deux codes
J'avais besoin des endroits imbriqués pour rechercher un utilisateur par plusieurs champs:
$users_query->where('company_uuid', '=', $company_uuid);
$users_query->where('is_active', '=', true);
$users_query->whereNested(function($query) use ($search){
/** @var Builder $query */
$query
->where('first_name', 'like', '%' . $search . '%')
->orWhere('last_name', 'like', '%' . $search . '%')
->orWhere('email', 'like', '%' . $search . '%');
});
Supposons que vous souhaitiez empiler where
couches sans les perdre en utilisant orWhere
Ne serait-ce pas la même chose?
$challenge = $this->challenges()
->where('open', true)
->whereNested(function($q) use ($user_id, $opponent_id) {
$query->where('player_1', $user_id)
->where('player_2', $opponent_id);
$query->orWhere('player_1', $opponent_id)
->where('player_2', $user_id);
})->first();