Besoin d'aide ?

Double relation N-N et recherche de donnée

Avatar de dawiteu
dawiteu

Bonjour, je suis en train de développer un projet assez complèxe et me voici bloqué. Pour comprendre l'histoire, il faut un petit résumé: -L'admin ajoute des Spheres et lui attribue des Usages. Une sphere peut avoir plusieurs Usages et les Usages peuvent être dans plusieurs Spheres en même temps. L'admin doit faire un préset pour l'utilisateur des configurations possibles:

  1. Sphere 1 Usage A Usage B Usage E

  2. Sphere 2 Usage A Usage B Usage C

  3. Sphere 3 Usage B Usage C

Avec ces informations, un utilisateur doit encoder des Plantes et y choisir (via checkboxes) les Spheres ET Usages (de la liste ci-haut) qui lui sont attribuées: Plante 1: Sphere 1: Usage B Usage E

Sphere 2: Usage B Usage C

Sphere 3: /

J'ai donc effectuer 3 modeles (Plantes, Spheres et Usages) qui sont reliés via des tables N-N. Image de la db

Maintenat je n'arrive pas a afficher, pour une plante, les spheres ET en dessous les usages qui lui sont attribués (et non prédéfinis par l'admin). De plus, comme il s'agit de tables N-N, j'ai très souvent l'erruer

SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias:

J'ai essayé de faire la requête en SQL simple (pour voir ce que ça peut donner) mais j'ai pas trouvé de bon résultats, d'autant plus que je n'ai pas réussi à regroupper les informations par sphere...

D'avance merci!

Posté il y a 1 mois
Avatar de CinquièmeDimension
CinquièmeDimension

Salut,

Ce que je comprends c'est qu'une sphère à plusieurs usage et un usage peut être dans plusieurs sphère. Donc n-n OK. C'est l'admin qui enregistre les sphere, usage et leur relations.

Le user ajoute des plante, et choisit plusieurs sphere et usage. Donc une plante est liée à 0-n sphere-usage. Mail faut donc que cette relation sphere-usage existe au préalable, ce qui peut être un difficulé à l'enregistrement.

Ton shema BDD est comme je l'aurai fait donc l'erreur vient probablement d'ailleurs. Tu dis que tu n'arrive pas à afficher, donc tu arrive à enregistrer ? C'est bien ça ?

Après, tout dépends comment tu veux l'afficher. Si c'est sur une page specifique à la plante du genre /plante/1 alors j'aurai fait simplement deux requètes pour aller chercher les sphère d'un côté et les usage de l'autre. La requête à faire dépends de comment tu as fait les relations. Donc un petut bout de code pour nous montrer ça peut-être ? Si, au contraire, c'est pour afficher sur une page recap de toutes les plantes, j'aurais récupéré toutes les données et triées en front dans une datatable.

Tu as peut-être fait un appel du genre ->select('name') au lieu de ->select('sphere.name') (donc l'erreur classique si tu as une joiture). Si tu pouvais nous donner ta requête ca aiderai, je pense que c'est juste un petit truc qui bloque.

Avatar de dawiteu
dawiteu

@CinquièmeDimension Merci pour ta réponse.

Quand je fais comme tu dis, /plante/1 Je souhaiterai afficher Uniquement les spheres qui y sont appropriés et à l'intérieur y regrouper les usages Mon code est erroné car la recherche est basée sur l'ID de la relation (sphere_usage) et c'est par la suite que je dois aller chercher le nom de la sphere et le nom de l'usage. Le problème est également au regrouppement, car il y a pas de identifiant unique, donc je reçois l'erreur: QLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias:

Avatar de CinquièmeDimension
CinquièmeDimension

Je n'ai pas tout compris. N'hésite pas à nous donner du code pour qu'on t'aide, là c'est difficile.

Dans la logique /plante/1, c'est l'ID de la plante qu'il faut, bien entendu, mettre. Avec l'id de la plante, tu fait un truc genre (example sale, sans vrai clée écrangère) :

Dans ton controller: $spheres_n_usages = Plante_sphere_usage::getSphereUsage($id);

Dans le model Plante_sphere_usage.php

public static function getSphereUsage ($id){
        $data = DB::table('plante_sphere_usage')
                ->select('*')
                ->join('sphere_usage','sphere_usage.id',"=","plate_sphere_usage.sphere_usage_id")
                ->join('sphere','sphere.id',"=","sphere_usage.sphere_id")
                ->join('usage','usage.id',"=","sphere_usage.usage_id")
                ->where('plante_sphere_usage.plante_id', $id)
                ->get();
        return $data;
 }

Ca c'est pour la totalité dans une seule query, sinon tu divise en deux genre:

public static function getSpheres ($id){
        $data = DB::table('plante_sphere_usage')
                ->select('*')
                ->join('sphere_usage','sphere_usage.id',"=","plate_sphere_usage.sphere_usage_id")
                ->join('sphere','sphere.id',"=","sphere_usage.sphere_id")
                ->where('plante_sphere_usage.plante_id', $id)
                ->groupBy('sphere.nom')
                ->orderBy('sphere.nom','ASC')
                ->get();
        return $data;
 }

C'est pas l'idéal, vu que mes requetes correspondent à des clés étrangères non relationnées, donc, comme je l'ai dit dans mon dernier post:

La requête à faire dépends de comment tu as fait les relations.

Avatar de dawiteu
dawiteu

Dans le modèle PlanteSphereUsage j'ai fais: $planteSU = PlanteSphereUsage:: select( 'plante_sphere_usage.id as id', 'plante_sphere_usage.plante_id as plante_id', 'plante_sphere_usage.sphere_usage_id as plsu_id', 'sphere_usage.sphere_id as sphere_id', 'spheres.nom as sphere_nom', 'usages.nom as usage_nom' ) ->LeftJoin('sphere_usage', 'plante_sphere_usage.sphere_usage_id', '=', 'sphere_usage.id') ->leftJoin('spheres', 'sphere_usage.sphere_id', '=', 'spheres.id') ->leftJoin('usages', 'sphere_usage.usage_id', '=', 'usages.id') //->groupBy('sphere_id') ->where('plante_id', $plante->id)->get();

Dans la view: @foreach ($planteSU as $psu) <p> {{ $psu }} </p> @endforeach Ce qui me donne un résultat plutôt correct (recherche d'élément par plante:

![s](https://imgupload.dawit.eu/storage/imageupload/lf1hSH82pdAPc3HZUT3JSJi5pIm4ckr2vHGAwsIU.png)

Maintenat reste le soucis pour regrouper les mêmes usages dans la même spheres (quand je décommente //->groupBy('sphere_id') , mysql me retourne une erreur : SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias:

En tout cas un grand merci pour ton aide!

Avatar de CinquièmeDimension
CinquièmeDimension

Essaie de preciser ton sphere_id en spheres.idou 'sphere_usage.sphere_id". Je pense que l'erreur vient de là

Avatar de dawiteu
dawiteu

Malheureusement, j'ai toujours une erreur: SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'psu.plante_sphere_usage.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

Avatar de CinquièmeDimension
CinquièmeDimension

Ce n'est pas du tout la même erreur donc c'est bien. Ca avance.

L'erreur viens vraisemblablement de psu.plante_sphere_usage.id Poste la dernière version de ta requete pour voir...

Vous ne pouvez pas répondre à ce sujet.