Laravel 5

Requête jointe et enregistrement multiples

  • Avatar de ArtemisLhow
    Membre depuis :
    06/12/2018
    Messages :
    13

    Bonsoir Laravelleurs !

    J'ai besoin d'un petit coup de pouce pour la bonne execution d'une requête SQL jointe ...

    Grosso modo j'ai besoin de récupérer les informations de trois tables (appellons les x / y / z). Les deux tables secondaires (y et z) doivent retourner les résultats qui correspondant à l'id de la table principale (x). Actuellement, voici ce que j'ai :

    $adherents = DB::table('adherents')
    ->select('x.colone as x_colone', 'y.colone as y_colone', 'z.colone as z_colone')
    ->leftJoin('y', 'x.id', '=', 'z.x_id')
    ->leftJoin('z', 'x.id', '=', 'z.x_id')
    ->orderBy('x.nom', 'asc')
    ->get();

    Et jusque là : tout va bien ! Je récupère bien l'ensemble des enregistrements et un foreach plus loin, tout est affiché à l'écran. Seulement, les tables y et z peuvent contenir plusieurs entrée correspondantes à une entrée de la table x. Et là c'est le bordel ! Parce que, pour une raison que je ne m'explique pas, si l'entrée x contient deux entrées dans la table y ... bah l'entrée x apparait deux fois dans la liste.

    J'ai bien essayé le distinct et le groupBy, mais rien n'y fait je ne trouve pas de solution viable... quelqu'un pourrait-il éclairer ma lanterne ?

    Dabisous !

    Artemis

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

    Salut,

    C'est le principe de base d'une jointure, tu as toutes les lignes.

  • Avatar de ArtemisLhow
    Membre depuis :
    06/12/2018
    Messages :
    13

    Salut !

    Je comprend bien et c'est le but que d'avoir tous les enregistrement ... le soucis c'est qu'il m'affiche plusieurs lignes pour un seul enregistrement ! En gros j'aimerai que tous les enregistrements y et x soient regroupés par enregistrement x. Là à l'heure actuelle j'ai des doublons dans ma liste parce que j'ai deux y pour un seul x... dommage non ?

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

    Si tu as deux y pour un seul x c'est que ce sont des enregistrements différents avec la jointure qui arrivent logiquement sur deux lignes et forcément tu as le doublon x. Peut-être qu'il serait plus efficace de passer par une relation ?

  • Avatar de ArtemisLhow
    Membre depuis :
    06/12/2018
    Messages :
    13

    C'est à dire ?

    Voilà ce que j'ai dans mes modèles adhérents et enfants (puisque c'est de ça qu'il s'agit) :

    // Model Adhérent
    public function Enfants()
    {
    return $this->hasMany('App\Models\Enfants', 'adherents_id');
    }

    public function Coordonnes()
    {
    return $this->hasOne('App\Models\Coordonnees', 'adherents_id');
    }

    public function ListeAdhesions()
    {
    return $this->hasMany('App\Models\Adhesions', 'adherents_id');
    }
    // Model Enfants
    public function Parents()
    {
    return $this->hasOne('App\Models\Adherents', 'id');
    }

    Je fais quoi avec ça ?

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

    Avec ça tu peux utiliser Eloquent pour faire des requêtes. Par exemple :

    $adherents = Adherent::with('Enfants', 'ListeAdhesions')->get();

    Tu as tous les adhérents avec leurs enfants et les listes d'adhésion. Après au niveau traitement par exemple :

    foreach($adherents as $adherent) {
    echo $adherent->nom . PHP_EOL;
    foreach($adherent->Enfants as $enfant) {
    echo $enfant->nom . PHP_EOL;
    }
    ...
    }
  • Avatar de ArtemisLhow
    Membre depuis :
    06/12/2018
    Messages :
    13

    Oh punaise, j'en était pas encore là dans mon utilisation du framework, mais les relations et l'utilisation de collections sont bien plus importantes / utiles que je ne le pensais ... merci à toi l'ami ta réponse corrige presque parfaitement mon problème !

    Après vérifications, si la chose fonctionne à merveille pour les enfants, pas moyen de récupèrer les coordonnées. J'arrive bien à voir les coordonnées avec un :

    dd($adherent->Coordonnees)

    Seulement quand je passe le tout au foreach j'ai droit à un joli :

    Trying to get property 'telephone_domicile' of non-object (0)

    J'ai loupé un truc ?

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

    Il faut charger les coordonnées alors :

    $adherents = Adherent::with('Enfants', 'Coordonnes')->get();
  • Avatar de ArtemisLhow
    Membre depuis :
    06/12/2018
    Messages :
    13

    Ah ah ! Je ne l'ai pas précisé, mais c'était fait bien évidement :D

    C'est pour ça que je ne comprend pas ce qui ne fonctionne pas ... le dd m'affiche bien mon array avec l'ensemble des valuers et propriétés de l'objet Coordonnées, et à côté de ça quand je veux l'afficher ...

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

    A priori il n'y a qu'un seul enregistrement des coodonnées alors pourquoi une boucle ?

  • Avatar de ArtemisLhow
    Membre depuis :
    06/12/2018
    Messages :
    13

    Effectivement, mais comment je récupère les données contenues dans ma variable ?

    J'ai essayé ces quelques lignes, mais sans succès...

    $adherent->Coordonnees->telephone_domicile
    $adherent->Coordonnees['telephone_domicile']
    $adherent->Coordonnees()->telephone_domicile
  • Avatar de bestmomo
    Membre depuis :
    07/04/2013
    Messages :
    2299

    Ca donne quoi dd($adherent->Coordonnees) ?

  • Avatar de ArtemisLhow
    Membre depuis :
    06/12/2018
    Messages :
    13
    Coordonnees {#592 ▼
    #table: "coordonnees"
    +timestamps: true
    #fillable: array:11 [▶]
    #connection: "mysql"
    #primaryKey: "id"
    #keyType: "int"
    +incrementing: true
    #with: []
    #withCount: []
    #perPage: 15
    +exists: true
    +wasRecentlyCreated: false
    #attributes: array:13 [▶]
    #original: array:13 [▶]
    #changes: []
    #casts: []
    #dates: []
    #dateFormat: null
    #appends: []
    #dispatchesEvents: []
    #observables: []
    #relations: []
    #touches: []
    #hidden: []
    #visible: []
    #guarded: array:1 [▶]
    }

    L'ensemble des données qui m'intéressent se trouvent dans le array attributes ...

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

    Si elle y sont alors tu dois pouvoir les récupérer...

  • Avatar de ArtemisLhow
    Membre depuis :
    06/12/2018
    Messages :
    13

    Elles y sont, mais aucune des méthodes employées ne donne le résultat escompté ...

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

    C'est quand même surprenant...

  • Avatar de ArtemisLhow
    Membre depuis :
    06/12/2018
    Messages :
    13

    Ne me demande pas, mais à présent ça marche... aucune idée de ce que j'ai bien pu merder sur ma requête précédente, mais c'est bon à présent !

    Dernier question rapport à cette méthode et je ne t'embête plus =p

    Tu as tout à fait raison de souligner que l'utilisation d'un foreach dans une relation hasOne n'est pas ce qu'il se fait de mieux pour traiter les données... mais comment accèder aux données autrement ?

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

    Eh bien tu accèdes directement aux données sans boucle puisque tu n'as qu'une valeur...

Vous ne pouvez pas répondre à ce sujet.