Besoin d'aide ?

Ecriture d'une requête

  • Avatar de JeremyPLANCHETTE
    Membre depuis :
    10/01/2019
    Messages :
    10

    Bonjour,

    Je suis en train d’élaborer une requête mais je bug complet dans l’écriture de celle-ci.

    Je dispose de 4 tables (j'ai simplifié pour la compréhension de mon problème):

    • activities
    • types
    • teams
    • positions

    • activities :
      --- id
      --- type_id
      --- team_id
      --- activity
      --- date_activity

    • types :
      --- id
      --- type

    • teams :
      --- id
      --- team

    • positions :
      --- id
      --- position

    • activities_positions (table pivot liant des positions à des activités)
      --- id
      --- activity_id
      --- position_id

    Maintenant je souhaite effectuer une requête pour récupérer mes activités avec les conditions suivantes : (activités comprises entre deux dates ET (activités réalisées par les équipes données OU activités réalisées sur les positions données))

    Pour mes variables d'entrées j'ai :

    // Equipes à filtrer :
    $teamsList = [1, 5, 7];

    // Positions à filtrer
    $positionsList=[1, 300, 58];

    // Dates limites
    $dateStart = '2018-01-01 00:00:00';
    $dateEnd='2018-06-06 23:00:00';

    C'est pour écrire cette requête que je bug complétement :

    // Pour filtrer dans la bonne plage de dates rien de plus simple :
    $activities = Activites::whereBetween('date_activity', [$dateStart, $dateEnd]);

    Pour filtrer mes équipes je pourrai bien faire :

    $activities = Activites::whereBetween('date', [$dateStart, $dateEnd])
    ->whereIn('team_id', $arrayListTeams_id);

    Mais après je ne vois du tout comment ajouter au filtre des dates la condition OU entre un array d'ID équipes et un array d'ID de positions dans ma table pivot.

    Je suis preneur d'un petit coup de pouce pour avancer :)

  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    2418

    Salut,

    Tu peux construire syntaxiquement comme ça :

    ->where(function ($query) {
    $query->where(...)
    ->orWhere(...);
    })
  • Avatar de JeremyPLANCHETTE
    Membre depuis :
    10/01/2019
    Messages :
    10

    Merci de m'avoir mis sur la piste bestmomo.

    Je suis parti sur ce code :

    $activities = Activities::whereBetween('date_activity', [$dateStart, $dateEnd])
    ->where(function ($query) use ($teamsList, $positionsList) {
    $query->whereIn('team_id', $teamsList);
    })
    ->get();

    Pour le moment ça me sort bien les bons enregistrements.

    Me manque plus qu'à effectuer la recherche des activités utilisant les positions données.

    Si je ne me trompe pas, j'aurai dû faire quelque chose de la sorte pour que ca fonctionne avec "compris entre les dates" ET "contient les positions).

    $activities = Activities::whereBetween('date_activity', [$dateStart, $dateEnd])
    ->with(['positions' => function ($query) use ($positionsList) {
    $query->wherePivotIn('position_id', $positionsList);}])
    ->get();

    Pour information, j'ai dans mon Modele "Activities" :

    public function positions() {
    return $this->belongsToMany(
    'App\Models\Positions',
    'activities_positions',
    'activity_id',
    'position_id')->orderBy('position', 'ASC');
    }

    N'ayant encore jamais "construit" des requêtes de la sorte, je ne vois pas comment intégrer le "orWherePivotIn" ?

  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    2418

    Pourquoi pas comme ça :

    $activities = Activities::whereBetween('date_activity', [$dateStart, $dateEnd])
    ->where(function ($query) use ($teamsList, $positionsList) {
    $query->whereIn('team_id', $teamsList)
    ->orWherePivotIn('position_id', $positionsList);
    })->get();
  • Avatar de JeremyPLANCHETTE
    Membre depuis :
    10/01/2019
    Messages :
    10

    Je viens d'essayer, j'ai le message d'erreur suivant :

    BadMethodCallException
    Call to undefined method Illuminate\Database\Eloquent\Builder::orWherePivotIn()

    Pour information je suis sous Laravel 5.7.

    Avec ta méthode, je me pose la question comment il fait pour savoir dans quelle tablea pivot il doit aller faire sa recherche ?

  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    2418

    Ah oui je suis allé un peu vite sur le truc... On peut placer ce genre de filtre que directement sur la relation...

    Après réflexion :

    $activities = Activities::whereBetween('date_activity', [$dateStart, $dateEnd])
    ->where(function ($query) use ($teamsList, $positionsList) {
    $query->whereHas('teams', function ($query) use ($teamsList) {
    $query->whereIn('teams.id', $teamsList);
    })->orWhereHas('positions', function ($query) use ($positionsList) {
    $query->whereIn('positions.id', $positionsList);
    })
    })->get();

    Il faut que les 2 relations aient été bien établiées.

  • Avatar de JeremyPLANCHETTE
    Membre depuis :
    10/01/2019
    Messages :
    10

    C'est nickel, ca fonctionne ! Pas à c___r c'est vraiment puissant pour l'élaboration des requêtes !

    Juste j'ai mis le code suivant : (la teamsList n'est pas dans une tableau pivot, je ne peux avoir qu'une équipe par activité)

    J'ai mis ce code :

    $activities = Activities::whereBetween('date', [$dateStart, $dateEnd])
    ->where(function ($query) use ($teamsList, $positionsList) {
    $query->whereIn('team_id', $teamsList)
    ->orWhereHas('positions', function ($query) use ($positionsList) {
    $query->whereIn('positions.id', $positionsId);
    });
    })
    ->get();

Vous ne pouvez pas répondre à ce sujet.