Relation ternaire

Une simple petite relation ternaire

Le problème exposé dans ce sujet a été résolu.

Bonjour,

Je réalise actuellement une application avec Symfony, je débute un peu dans l'utilisation de ce framework.

Ma question comme le titre l'indique porte sur la création et l'utilisation d'une relation ternaire.

Je dispose de trois entités : 1. Ligne 2. Arrêt 3. Horaire

Jusque la pas trop de soucis, pour la création pas vraiment de problème.

On a les relations suivantes : - Une ligne et une arrêt donne une liste d'horaire pour cette ligne à cet arrêt - Une ligne et un horaire donne un arrêt en particulier. - Un arrêt et un horaire donne une ligne en particulier.

Dans le cadre de mon application, j'ai surtout besoin à partir de l'entité Ligne et avec un objet Arrêt, de récupérer la liste des horaires qui spécifique à cette ligne à cet arrêt.

Il faudrait donc quelque chose du genre :

1
$ligne->getHoraires($arrêt);

qui me retourne la liste des horaires de cette ligne, à cet arrêt. Ayant déjà les getters de base des relations entre entités, notamment le getHoraires() pour l'entité Ligne, je pourrais parcourir cette liste et extraire uniquement les horaires avec le bon arrêt, mais je trouve cette méthode peu propre.

L'idéal, je pense, serait de pouvoir définir la requête qui est simplement un WHERE avec deux conditions l'une portant sur la ligne et l'autre sur l'arrêt dans la table horaire. Je ne vois malheureusement pas comment agencer mon code pour faire cela de manière "propre" à mon goût et au goût de Symfony.

Si vous avez des idées, ou des suggestions, je suis preneur.

Merci :)

+0 -0

Hello,

En somme, je suppose que tu as ce type de relation :

Ligne -> One to Many -> Horaires <- Many to One <- Arret ?

Dans ce cas, on se retrouve dans un cas typique d'une ManyToMany, mais "avec attributs" (soit ici l'heure), en ayant une clé primaire dite "composite" (sur plusieurs champs à la fois). Si tu utilises Doctrine, tu pourras trouver un peu de doc là dessus.

Mais en revenant un peu sur le sujet, faire un filtre sur une collection est le meilleur plan en fait, plutôt que de chercher à faire une requête un poil trop spécifique… Surtout qu'en général, il est bon de faire directement lors de la requête qui va chercher ta Ligne et ton Arrêt de faire les jointures qui vont avec, qui elles récupèrent tout d'un coup.

+0 -0

Salut,

Déjà merci d'avoir pris le temps de me répondre,

J'ai pas mal regardé du côté du ManyToMany avec "attributs", notamment le tutoriel de winzou qui en parle pas mal avec les Repository, mais j'avais cru trouver une limite dans le fait que ce que je recherche exactement c'est quelque chose du genre :

  • Je récupère un arrêt, cet arrêt contient une liste de ligne (plusieurs ligne passe au même arrêt), et chaque ligne possèdes des horaires. Si je fais ça :
1
2
3
{% for ligne in stop.ligne %}
  {{ ligne.horaires }}
{% endfor %}

Je vais avoir tous les horaires de passage sur la ligne quelque soit l'arrêt. Ce n'est pas ce que je veux.

Ce que j'aimerai dans le meilleur des mondes, c'est que sans toucher au code de ma vue j'obtienne uniquement les horaires à cet arrêt, je sais que c'est impossible de par la construction de Doctrine.

Donc je voudrais avec quelque chose comme ça :

1
2
3
{% for ligne in stop.ligne %}
  {{ ligne.horaires(stop) }}
{% endfor %}

Je pense qu'en créant un attribut virtuel (et donc un getter associé), il est possible de filtrer la liste des horaires à ce niveau, c'est finalement la deuxième méthode que tu proposes Talus, la requête sera un peu moins efficace mais ça évitera de se casser le cul sur une requête bien compliqué pour cherche ce qu'on a besoin. Après je sais pas trop comment ça se goupille avec Sf2, va falloir chercher.

Edit:

En fait, l’idéal serait avec un Repository sur Horaire, faire une méthode pour récupérer les horaires d'un Arrêt et d'une Ligne (donc un truc du genre

1
$HoraireRepository->getByArretandLigne($arret,$ligne);

Puis associer cette méthode à un attribut virtuel de la classe Ligne et/ou Arrêt afin de récupérer une liste d'horaires qui correspond à arrêt et ligne en même temps.

+0 -0

En répondant à ton edit, oui, c'est comme ça que tu dois en fait procéder ; sélectionner / joindre les arrêts / horaires lorsque tu sélectionnes une ligne (ou lignes / horaires si ce sont les arrêts que tu veux), et l'idée serait de mettre en effet une sorte de getter qui te filtre les horaires suivant l'arrêt désiré (ou la ligne désirée si t'es dans un arrêt).

Par contre, tu ne devrai pas avoir de répo sur une table qui fait la liaison entre deux autres.

1
2
3
4
5
6
7
<?php

/// ....
public function getHoraires(Arret $arret)
{
    return $this->horaires->filter(function (Horaire $horaire) { return $arret->getId() === $horaire->getArret()->getId(); /* ou $arret === $horaire->getArret(), mais on sait jamais, les objets *peuvent* être différents */ });
} 

En très gros, mais faut s'assurer que les horaires (et arrêts associés) soient bien joints lors de la requête de selection de la ligne (et inversement pour une sélection d'un arret).

+0 -0

Et ben pinaise, je recherchais avec les mauvais mots clefs jusqu'ici. Avec ton idée de filtre, j'ai fait quelques recherches et je suis tombé sur exactement le même problème que moi. ;)

Dans l'article suivant, la personne utilise la class Criteria qui permet de faire les bonnes sélections et ça marche vraiment bien !

Merci pour ton aide Talus. :)

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte